Upgrade SFTP Uploader

- now allows reading files from SFTP in Shinobi UI
- now manages space used on SFTP, auto deletes oldest on over max
upgrade-sftp-uploader
Moe 2022-08-09 08:29:31 -07:00
parent 55b850c6f7
commit 999d80ea55
3 changed files with 275 additions and 119 deletions

View File

@ -1,7 +1,26 @@
var fs = require('fs'); var fs = require('fs');
const { NodeSSH } = require('node-ssh'); const Whoosh = require('whoosh');
module.exports = function(s,config,lang){ module.exports = function(s,config,lang){
//SFTP //SFTP
const storageType = 'sftp'
function createSftpClient(user){
return new Promise((resolve) => {
const connectionDetails = {
host: userDetails.sftp_host,
port: parseInt(userDetails.sftp_port) || 22,
}
if(userDetails.sftp_username && userDetails.sftp_username !== '')connectionDetails.username = userDetails.sftp_username
if(userDetails.sftp_password && userDetails.sftp_password !== '')connectionDetails.password = userDetails.sftp_password
if(userDetails.sftp_privateKey && userDetails.sftp_privateKey !== '')connectionDetails.privateKey = userDetails.sftp_privateKey
Whoosh.connect(connectionDetails,(err, client) => {
if(error)sftpErr(user.ke,error);
resolve({
error,
sftp: client,
})
});
})
}
var sftpErr = function(groupKey,err){ var sftpErr = function(groupKey,err){
s.userLog({mid:'$USER',ke:groupKey},{type:lang['SFTP Error'],msg:err.data || err}) s.userLog({mid:'$USER',ke:groupKey},{type:lang['SFTP Error'],msg:err.data || err})
} }
@ -28,26 +47,19 @@ module.exports = function(s,config,lang){
if(userDetails.sftp_dir !== ''){ if(userDetails.sftp_dir !== ''){
userDetails.sftp_dir = s.checkCorrectPathEnding(userDetails.sftp_dir) userDetails.sftp_dir = s.checkCorrectPathEnding(userDetails.sftp_dir)
} }
const sftp = new NodeSSH(); const { sftp, error } = await createSftpClient(e);
const connectionDetails = { if(!error)s.group[e.ke].sftp = sftp;
host: userDetails.sftp_host,
port: userDetails.sftp_port || 22,
}
if(userDetails.sftp_username && userDetails.sftp_username !== '')connectionDetails.username = userDetails.sftp_username
if(userDetails.sftp_password && userDetails.sftp_password !== '')connectionDetails.password = userDetails.sftp_password
if(userDetails.sftp_privateKey && userDetails.sftp_privateKey !== '')connectionDetails.privateKey = userDetails.sftp_privateKey
sftp.connect(connectionDetails).catch((err) => {
sftpErr(e.ke,err)
})
s.group[e.ke].sftp = sftp
} }
} }
var unloadSftpForUser = function(user){ var unloadSftpForUser = function(user){
if(s.group[user.ke].sftp && s.group[user.ke].sftp.end)s.group[user.ke].sftp.end().then(function(){ const sftp = s.group[user.ke].sftp
if(sftp && sftp.disconnect){
sftp.disconnect(function(){
s.group[user.ke].sftp = null s.group[user.ke].sftp = null
}) })
} }
var uploadVideoToSftp = function(e,k){ }
function uploadVideoToSftp(e,k){
//e = video object //e = video object
//k = temporary values //k = temporary values
if(!k)k={}; if(!k)k={};
@ -55,8 +67,8 @@ module.exports = function(s,config,lang){
if(s.group[e.ke].sftp && s.group[e.ke].init.use_sftp !== '0' && s.group[e.ke].init.sftp_save === '1'){ if(s.group[e.ke].sftp && s.group[e.ke].init.use_sftp !== '0' && s.group[e.ke].init.sftp_save === '1'){
var localPath = k.dir + k.filename var localPath = k.dir + k.filename
var saveLocation = s.group[e.ke].init.sftp_dir + e.ke + '/' + e.mid + '/' + k.filename var saveLocation = s.group[e.ke].init.sftp_dir + e.ke + '/' + e.mid + '/' + k.filename
s.group[e.ke].sftp.putFile(localPath, saveLocation).catch((err) => { s.group[e.ke].sftp.fastPut(saveLocation, saveLocation,(err) => {
sftpErr(e.ke,err) if(err)sftpErr(e.ke,err)
}) })
} }
} }
@ -73,22 +85,104 @@ module.exports = function(s,config,lang){
createSftpDirectory(monitorConfig) createSftpDirectory(monitorConfig)
} }
} }
function cloudDiskUseStartup(group,userDetails){
const diskUseObject = group.cloudDiskUse[storageType]
diskUseObject.name = 'SFTP'
diskUseObject.sizeLimitCheck = (userDetails.use_sftp_size_limit === '1')
if(!userDetails.sftp_size_limit || userDetails.sftp_size_limit === ''){
diskUseObject.sizeLimit = 10000
}else{
diskUseObject.sizeLimit = parseFloat(userDetails.sftp_size_limit)
}
}
var onAccountSaveForSftp = function(group,userDetails,user){ var onAccountSaveForSftp = function(group,userDetails,user){
if(s.group[user.ke] && s.group[user.ke].sftp && s.group[user.ke].init.use_sftp !== '0' && s.group[user.ke].init.sftp_save === '1'){ if(s.group[user.ke] && s.group[user.ke].sftp && s.group[user.ke].init.use_sftp !== '0' && s.group[user.ke].init.sftp_save === '1'){
Object.keys(s.group[user.ke].rawMonitorConfigurations).forEach(function(monitorId){ Object.keys(s.group[user.ke].rawMonitorConfigurations).forEach(function(monitorId){
createSftpDirectory(s.group[user.ke].rawMonitorConfigurations[monitorId]) createSftpDirectory(s.group[user.ke].rawMonitorConfigurations[monitorId])
}) })
} }
cloudDiskUseStartup(group,userDetails)
}
function deleteFile(user,video,callback){
// e = user
const sftp = s.group[user.ke].sftp
try{
var videoDetails = JSON.parse(video.details)
}catch(err){
var videoDetails = video.details
}
if(videoDetails.type !== storageType){
return
}
if(!videoDetails.location){
videoDetails.location = video.href.split('.amazonaws.com')[1]
}
sftp.unlink(videoDetails.location,function(err){
if (err) console.log(err);
callback()
})
}
function onInsertTimelapseFrame(monitorObject,queryInfo,filePath){
const e = monitorObject
const sftp = s.group[monitorObject.ke].sftp
if(sftp && s.group[e.ke].init.use_sftp !== '0' && s.group[e.ke].init.sftp_save === '1'){
var fileStream = fs.createReadStream(filePath)
fileStream.on('error', function (err) {
console.error(err)
})
var saveLocation = s.group[e.ke].init.sftp_dir + e.ke + '/' + e.mid + '_timelapse/' + queryInfo.filename
s.group[e.ke].sftp.fastPut(filePath, saveLocation,(err) => {
if(err)sftpErr(e.ke,err)
if(err){
sftpErr(e.ke,err)
}
if(s.group[e.ke].init.sftp_log === '1'){
s.knexQuery({
action: "insert",
table: "Cloud Timelapse Frames",
insert: {
mid: queryInfo.mid,
ke: queryInfo.ke,
time: queryInfo.time,
filename: queryInfo.filename,
details: s.s({
type : storageType,
location : saveLocation
}),
size: queryInfo.size,
href: ''
}
})
s.setCloudDiskUsedForGroup(e.ke,{
amount : s.kilobyteToMegabyte(queryInfo.size),
storageType : storageType
},'timelapseFrames')
s.purgeCloudDiskForGroup(e,storageType,'timelapseFrames')
}
})
}
}
await function onGetVideoData(video){
const sftp = s.group[video.ke].sftp
const videoDetails = s.parseJSON(video.details)
const saveLocation = videoDetails.location
const fileStream = sftp.createReadStream(saveLocation)
return fileStream
} }
//SFTP (Simple Uploader) //SFTP (Simple Uploader)
s.addSimpleUploader({ s.addCloudUploader({
name: 'sftp', name: 'sftp',
loadGroupAppExtender: loadSftpForUser, loadGroupAppExtender: loadSftpForUser,
unloadGroupAppExtender: unloadSftpForUser, unloadGroupAppExtender: unloadSftpForUser,
insertCompletedVideoExtender: uploadVideoToSftp, insertCompletedVideoExtender: uploadVideoToSftp,
deleteVideoFromCloudExtensions: deleteFile,
cloudDiskUseStartupExtensions: cloudDiskUseStartup,
beforeAccountSave: beforeAccountSaveForSftp, beforeAccountSave: beforeAccountSaveForSftp,
onAccountSave: onAccountSaveForSftp, onAccountSave: onAccountSaveForSftp,
onMonitorSave: onMonitorSaveForSftp, onMonitorSave: onMonitorSaveForSftp,
onInsertTimelapseFrame: onInsertTimelapseFrame,
onDeleteTimelapseFrameFromCloud: deleteFile,
onGetVideoData
}) })
return { return {
"evaluation": "details.use_sftp !== '0'", "evaluation": "details.use_sftp !== '0'",
@ -99,9 +193,7 @@ module.exports = function(s,config,lang){
"name": "detail=sftp_save", "name": "detail=sftp_save",
"selector":"autosave_sftp", "selector":"autosave_sftp",
"field": lang.Autosave, "field": lang.Autosave,
"description": "",
"default": lang.No, "default": lang.No,
"example": "",
"fieldType": "select", "fieldType": "select",
"possible": [ "possible": [
{ {
@ -119,30 +211,18 @@ module.exports = function(s,config,lang){
"field": lang.Host, "field": lang.Host,
"name": "detail=sftp_host", "name": "detail=sftp_host",
"form-group-class": "autosave_sftp_input autosave_sftp_1", "form-group-class": "autosave_sftp_input autosave_sftp_1",
"description": "",
"default": "",
"example": "",
"possible": ""
}, },
{ {
"hidden": true, "hidden": true,
"field": lang.Port, "field": lang.Port,
"name": "detail=sftp_port", "name": "detail=sftp_port",
"form-group-class": "autosave_sftp_input autosave_sftp_1", "form-group-class": "autosave_sftp_input autosave_sftp_1",
"description": "",
"default": "",
"example": "",
"possible": ""
}, },
{ {
"hidden": true, "hidden": true,
"field": lang.Username, "field": lang.Username,
"name": "detail=sftp_username", "name": "detail=sftp_username",
"form-group-class": "autosave_sftp_input autosave_sftp_1", "form-group-class": "autosave_sftp_input autosave_sftp_1",
"description": "",
"default": "",
"example": "",
"possible": ""
}, },
{ {
"hidden": true, "hidden": true,
@ -150,10 +230,6 @@ module.exports = function(s,config,lang){
"fieldType": "password", "fieldType": "password",
"name": "detail=sftp_password", "name": "detail=sftp_password",
"form-group-class": "autosave_sftp_input autosave_sftp_1", "form-group-class": "autosave_sftp_input autosave_sftp_1",
"description": "",
"default": "",
"example": "",
"possible": ""
}, },
{ {
"hidden": true, "hidden": true,
@ -161,20 +237,58 @@ module.exports = function(s,config,lang){
"fieldType": "textarea", "fieldType": "textarea",
"name": "detail=sftp_privateKey", "name": "detail=sftp_privateKey",
"form-group-class": "autosave_sftp_input autosave_sftp_1", "form-group-class": "autosave_sftp_input autosave_sftp_1",
"description": "",
"default": "",
"example": "",
"possible": ""
}, },
{ {
"hidden": true, "hidden": true,
"name": "detail=sftp_dir", "name": "detail=sftp_dir",
"field": lang['Save Directory'], "field": lang['Save Directory'],
"form-group-class":"autosave_sftp_input autosave_sftp_1", "form-group-class":"autosave_sftp_input autosave_sftp_1",
"description": "",
"default": "/", "default": "/",
"example": "", },
"possible": "" {
"hidden": true,
"name": "detail=sftp_log",
"field": lang['Save Links to Database'],
"fieldType": "select",
"selector": "h_sftpsld",
"form-group-class":"autosave_sftp_input autosave_sftp_1",
"possible": [
{
"name": lang.No,
"value": "0"
},
{
"name": lang.Yes,
"value": "1"
}
]
},
{
"hidden": true,
"name": "detail=use_sftp_size_limit",
"field": lang['Use Max Storage Amount'],
"fieldType": "select",
"selector": "h_s3zl",
"form-group-class":"autosave_sftp_input autosave_sftp_1",
"form-group-class-pre-layer":"h_sftpsld_input h_sftpsld_1",
"possible": [
{
"name": lang.No,
"value": "0"
},
{
"name": lang.Yes,
"value": "1"
}
]
},
{
"hidden": true,
"name": "detail=sftp_size_limit",
"field": lang['Max Storage Amount'],
"form-group-class":"autosave_sftp_input autosave_sftp_1",
"form-group-class-pre-layer":"h_sftpsld_input h_sftpsld_1",
"default": "10000",
}, },
] ]
} }

187
package-lock.json generated
View File

@ -51,7 +51,8 @@
"socket.io-client": "^4.4.1", "socket.io-client": "^4.4.1",
"tree-kill": "1.2.2", "tree-kill": "1.2.2",
"unzipper": "0.10.11", "unzipper": "0.10.11",
"webdav-fs": "^4.0.1" "webdav-fs": "^4.0.1",
"whoosh": "^2.0.1"
}, },
"bin": { "bin": {
"shinobi": "camera.js" "shinobi": "camera.js"
@ -740,14 +741,14 @@
} }
}, },
"node_modules/busboy": { "node_modules/busboy": {
"version": "0.3.1", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
"integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
"dependencies": { "dependencies": {
"dicer": "0.3.0" "streamsearch": "^1.1.0"
}, },
"engines": { "engines": {
"node": ">=4.5.0" "node": ">=10.16.0"
} }
}, },
"node_modules/bytes": { "node_modules/bytes": {
@ -1154,9 +1155,9 @@
} }
}, },
"node_modules/cpu-features": { "node_modules/cpu-features": {
"version": "0.0.3", "version": "0.0.4",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.3.tgz", "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz",
"integrity": "sha512-p6C/uud4F4bDyCz9+BNU22KdV1AGxPK6L9rQG9x3x4SSzdMPyBPErP7Rxn8avT2ex1M2g5Rpjz5Us/ri/766Qg==", "integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==",
"hasInstallScript": true, "hasInstallScript": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
@ -1284,17 +1285,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/dicer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
"integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
"dependencies": {
"streamsearch": "0.1.2"
},
"engines": {
"node": ">=4.5.0"
}
},
"node_modules/digest-fetch": { "node_modules/digest-fetch": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.1.tgz", "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.1.tgz",
@ -1915,14 +1905,14 @@
} }
}, },
"node_modules/express-fileupload": { "node_modules/express-fileupload": {
"version": "1.2.1", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.2.1.tgz", "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.0.tgz",
"integrity": "sha512-fWPNAkBj+Azt9Itmcz/Reqdg3LeBfaXptDEev2JM8bCC0yDptglCnlizhf0YZauyU5X/g6v7v4Xxqhg8tmEfEA==", "integrity": "sha512-RjzLCHxkv3umDeZKeFeMg8w7qe0V09w3B7oGZprr/oO2H/ISCgNzuqzn7gV3HRWb37GjRk429CCpSLS2KNTqMQ==",
"dependencies": { "dependencies": {
"busboy": "^0.3.1" "busboy": "^1.6.0"
}, },
"engines": { "engines": {
"node": ">=8.0.0" "node": ">=12.0.0"
} }
}, },
"node_modules/extend": { "node_modules/extend": {
@ -3652,9 +3642,9 @@
} }
}, },
"node_modules/moment": { "node_modules/moment": {
"version": "2.29.1", "version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
"engines": { "engines": {
"node": "*" "node": "*"
} }
@ -3832,9 +3822,9 @@
} }
}, },
"node_modules/nan": { "node_modules/nan": {
"version": "2.15.0", "version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==",
"optional": true "optional": true
}, },
"node_modules/nanomatch": { "node_modules/nanomatch": {
@ -5442,9 +5432,9 @@
} }
}, },
"node_modules/ssh2": { "node_modules/ssh2": {
"version": "1.8.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.8.0.tgz", "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz",
"integrity": "sha512-NVIRkIwJvWl+mcRozp+EBzHMVCcbDKBea64ToPdZEk43yAVGwmfqYZRPFRnnvGjsKC34wYCmiupTcKgCVNVNNg==", "integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"asn1": "^0.2.4", "asn1": "^0.2.4",
@ -5454,8 +5444,8 @@
"node": ">=10.16.0" "node": ">=10.16.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"cpu-features": "0.0.3", "cpu-features": "~0.0.4",
"nan": "^2.15.0" "nan": "^2.16.0"
} }
}, },
"node_modules/sshpk": { "node_modules/sshpk": {
@ -5597,11 +5587,11 @@
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
}, },
"node_modules/streamsearch": { "node_modules/streamsearch": {
"version": "0.1.2", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
"engines": { "engines": {
"node": ">=0.8.0" "node": ">=10.0.0"
} }
}, },
"node_modules/string_decoder": { "node_modules/string_decoder": {
@ -6372,6 +6362,40 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
}, },
"node_modules/whoosh": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/whoosh/-/whoosh-2.0.1.tgz",
"integrity": "sha512-bEEWr8t+Z5XfNREODH7m/bEXMe/veVBS99zj+JptP/yyYchtgd3s0XejBgWvpOfOrqRn9MQsXRHGFpqqWuDEJA==",
"dependencies": {
"debug": "^4.3.4",
"lodash": "^4.17.21",
"ssh2": "^1.10.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/whoosh/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/whoosh/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
@ -7009,11 +7033,11 @@
} }
}, },
"busboy": { "busboy": {
"version": "0.3.1", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
"integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
"requires": { "requires": {
"dicer": "0.3.0" "streamsearch": "^1.1.0"
} }
}, },
"bytes": { "bytes": {
@ -7348,9 +7372,9 @@
} }
}, },
"cpu-features": { "cpu-features": {
"version": "0.0.3", "version": "0.0.4",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.3.tgz", "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz",
"integrity": "sha512-p6C/uud4F4bDyCz9+BNU22KdV1AGxPK6L9rQG9x3x4SSzdMPyBPErP7Rxn8avT2ex1M2g5Rpjz5Us/ri/766Qg==", "integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==",
"optional": true, "optional": true,
"requires": { "requires": {
"buildcheck": "0.0.3", "buildcheck": "0.0.3",
@ -7441,14 +7465,6 @@
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc="
}, },
"dicer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
"integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
"requires": {
"streamsearch": "0.1.2"
}
},
"digest-fetch": { "digest-fetch": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.1.tgz", "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.1.tgz",
@ -7915,11 +7931,11 @@
} }
}, },
"express-fileupload": { "express-fileupload": {
"version": "1.2.1", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.2.1.tgz", "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.0.tgz",
"integrity": "sha512-fWPNAkBj+Azt9Itmcz/Reqdg3LeBfaXptDEev2JM8bCC0yDptglCnlizhf0YZauyU5X/g6v7v4Xxqhg8tmEfEA==", "integrity": "sha512-RjzLCHxkv3umDeZKeFeMg8w7qe0V09w3B7oGZprr/oO2H/ISCgNzuqzn7gV3HRWb37GjRk429CCpSLS2KNTqMQ==",
"requires": { "requires": {
"busboy": "^0.3.1" "busboy": "^1.6.0"
} }
}, },
"extend": { "extend": {
@ -9204,9 +9220,9 @@
} }
}, },
"moment": { "moment": {
"version": "2.29.1", "version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
}, },
"mp4frag": { "mp4frag": {
"version": "0.2.0", "version": "0.2.0",
@ -9340,9 +9356,9 @@
} }
}, },
"nan": { "nan": {
"version": "2.15.0", "version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==",
"optional": true "optional": true
}, },
"nanomatch": { "nanomatch": {
@ -10594,14 +10610,14 @@
"integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A="
}, },
"ssh2": { "ssh2": {
"version": "1.8.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.8.0.tgz", "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz",
"integrity": "sha512-NVIRkIwJvWl+mcRozp+EBzHMVCcbDKBea64ToPdZEk43yAVGwmfqYZRPFRnnvGjsKC34wYCmiupTcKgCVNVNNg==", "integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==",
"requires": { "requires": {
"asn1": "^0.2.4", "asn1": "^0.2.4",
"bcrypt-pbkdf": "^1.0.2", "bcrypt-pbkdf": "^1.0.2",
"cpu-features": "0.0.3", "cpu-features": "~0.0.4",
"nan": "^2.15.0" "nan": "^2.16.0"
} }
}, },
"sshpk": { "sshpk": {
@ -10713,9 +10729,9 @@
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
}, },
"streamsearch": { "streamsearch": {
"version": "0.1.2", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="
}, },
"string_decoder": { "string_decoder": {
"version": "1.3.0", "version": "1.3.0",
@ -11370,6 +11386,31 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
}, },
"whoosh": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/whoosh/-/whoosh-2.0.1.tgz",
"integrity": "sha512-bEEWr8t+Z5XfNREODH7m/bEXMe/veVBS99zj+JptP/yyYchtgd3s0XejBgWvpOfOrqRn9MQsXRHGFpqqWuDEJA==",
"requires": {
"debug": "^4.3.4",
"lodash": "^4.17.21",
"ssh2": "^1.10.0"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"wrap-ansi": { "wrap-ansi": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",

View File

@ -57,7 +57,8 @@
"socket.io-client": "^4.4.1", "socket.io-client": "^4.4.1",
"tree-kill": "1.2.2", "tree-kill": "1.2.2",
"unzipper": "0.10.11", "unzipper": "0.10.11",
"webdav-fs": "^4.0.1" "webdav-fs": "^4.0.1",
"whoosh": "^2.0.1"
}, },
"bin": "camera.js", "bin": "camera.js",
"scripts": { "scripts": {