Fix Dependency Vulnerabilities
- Telegram Bot module must be installed manually due to vulnerabilities - FTP Server module must be installed manually due to vulnerabilities - WebDAV module must be installed manually due to vulnerabilities and conf.json must configured manually to enable it. - Backblaze B2 module fork latest from git and published under shinobi-backblaze-b2rally-management
parent
879b5a6bae
commit
76b662a139
|
@ -164,13 +164,17 @@ module.exports = function(s,config,lang,app,io){
|
|||
})
|
||||
}
|
||||
var createDropInEventsDirectory = function(){
|
||||
if(!config.dropInEventsDir){
|
||||
config.dropInEventsDir = s.dir.streams + 'dropInEvents/'
|
||||
}
|
||||
s.dir.dropInEvents = s.checkCorrectPathEnding(config.dropInEventsDir)
|
||||
//dropInEvents dir
|
||||
if(!fs.existsSync(s.dir.dropInEvents)){
|
||||
fs.mkdirSync(s.dir.dropInEvents)
|
||||
try{
|
||||
if(!config.dropInEventsDir){
|
||||
config.dropInEventsDir = s.dir.streams + 'dropInEvents/'
|
||||
}
|
||||
s.dir.dropInEvents = s.checkCorrectPathEnding(config.dropInEventsDir)
|
||||
//dropInEvents dir
|
||||
if(!fs.existsSync(s.dir.dropInEvents)){
|
||||
fs.mkdirSync(s.dir.dropInEvents)
|
||||
}
|
||||
}catch(err){
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
var getDropInEventDir = function(monitorConfig){
|
||||
|
@ -209,58 +213,65 @@ module.exports = function(s,config,lang,app,io){
|
|||
createDropInEventDirectory(monitorConfig,function(err,monitorEventDropDir){})
|
||||
}
|
||||
// FTP Server
|
||||
createDropInEventsDirectory()
|
||||
if(config.ftpServer === true){
|
||||
createDropInEventsDirectory()
|
||||
if(!config.ftpServerPort)config.ftpServerPort = 21
|
||||
if(!config.ftpServerUrl)config.ftpServerUrl = `ftp://0.0.0.0:${config.ftpServerPort}`
|
||||
if(!config.ftpServerPasvUrl)config.ftpServerPasvUrl = config.ftpServerUrl.replace(/.*:\/\//, '').replace(/:.*/, '');
|
||||
if(!config.ftpServerPasvMinPort)config.ftpServerPasvMinPort = 10050;
|
||||
if(!config.ftpServerPasvMaxPort)config.ftpServerPasvMaxPort = 10100;
|
||||
config.ftpServerUrl = config.ftpServerUrl.replace('{{PORT}}',config.ftpServerPort)
|
||||
const FtpSrv = require('ftp-srv')
|
||||
try{
|
||||
const FtpSrv = require('ftp-srv')
|
||||
console.error('WARNING : FTP Server is enabled.')
|
||||
if(!config.ftpServerPort)config.ftpServerPort = 21
|
||||
if(!config.ftpServerUrl)config.ftpServerUrl = `ftp://0.0.0.0:${config.ftpServerPort}`
|
||||
if(!config.ftpServerPasvUrl)config.ftpServerPasvUrl = config.ftpServerUrl.replace(/.*:\/\//, '').replace(/:.*/, '');
|
||||
if(!config.ftpServerPasvMinPort)config.ftpServerPasvMinPort = 10050;
|
||||
if(!config.ftpServerPasvMaxPort)config.ftpServerPasvMaxPort = 10100;
|
||||
config.ftpServerUrl = config.ftpServerUrl.replace('{{PORT}}',config.ftpServerPort)
|
||||
|
||||
const ftpServer = new FtpSrv({
|
||||
url: config.ftpServerUrl,
|
||||
// pasv_url must be set to enable PASV; ftp-srv uses its known IP if given 127.0.0.1,
|
||||
// and smart clients will ignore the IP anyway. Some Dahua IP cams require PASV mode.
|
||||
// ftp-srv just wants an IP only (no protocol or port)
|
||||
pasv_url: config.ftpServerPasvUrl,
|
||||
pasv_min: config.ftpServerPasvMinPort,
|
||||
pasv_max: config.ftpServerPasvMaxPort,
|
||||
greeting: "Shinobi FTP dropInEvent Server says hello!",
|
||||
log: require('bunyan').createLogger({
|
||||
name: 'ftp-srv',
|
||||
level: 100
|
||||
}),
|
||||
})
|
||||
|
||||
ftpServer.on('login', ({connection, username, password}, resolve, reject) => {
|
||||
s.basicOrApiAuthentication(username,password,function(err,user){
|
||||
if(user){
|
||||
connection.on('STOR', (error, fileName) => {
|
||||
if(!fileName)return;
|
||||
var pathPieces = fileName.replace(s.dir.dropInEvents,'').split('/')
|
||||
var ke = pathPieces[0]
|
||||
var mid = pathPieces[1]
|
||||
var firstDroppedPart = pathPieces[2]
|
||||
var monitorEventDropDir = s.dir.dropInEvents + ke + '/' + mid + '/'
|
||||
var deleteKey = monitorEventDropDir + firstDroppedPart
|
||||
onFileOrFolderFound(monitorEventDropDir + firstDroppedPart,deleteKey,Object.assign({},s.group[ke].rawMonitorConfigurations[mid]))
|
||||
})
|
||||
resolve({root: s.dir.dropInEvents + user.ke})
|
||||
}else{
|
||||
// reject(new Error('Failed Authorization'))
|
||||
}
|
||||
const ftpServer = new FtpSrv({
|
||||
url: config.ftpServerUrl,
|
||||
// pasv_url must be set to enable PASV; ftp-srv uses its known IP if given 127.0.0.1,
|
||||
// and smart clients will ignore the IP anyway. Some Dahua IP cams require PASV mode.
|
||||
// ftp-srv just wants an IP only (no protocol or port)
|
||||
pasv_url: config.ftpServerPasvUrl,
|
||||
pasv_min: config.ftpServerPasvMinPort,
|
||||
pasv_max: config.ftpServerPasvMaxPort,
|
||||
greeting: "Shinobi FTP dropInEvent Server says hello!",
|
||||
log: require('bunyan').createLogger({
|
||||
name: 'ftp-srv',
|
||||
level: 100
|
||||
}),
|
||||
})
|
||||
})
|
||||
ftpServer.on('client-error', ({connection, context, error}) => {
|
||||
console.log('client-error',error)
|
||||
})
|
||||
ftpServer.listen().then(() => {
|
||||
s.systemLog(`FTP Server running on port ${config.ftpServerPort}...`)
|
||||
}).catch(function(err){
|
||||
s.systemLog(err)
|
||||
})
|
||||
|
||||
ftpServer.on('login', ({connection, username, password}, resolve, reject) => {
|
||||
s.basicOrApiAuthentication(username,password,function(err,user){
|
||||
if(user){
|
||||
connection.on('STOR', (error, fileName) => {
|
||||
if(!fileName)return;
|
||||
var pathPieces = fileName.replace(s.dir.dropInEvents,'').split('/')
|
||||
var ke = pathPieces[0]
|
||||
var mid = pathPieces[1]
|
||||
var firstDroppedPart = pathPieces[2]
|
||||
var monitorEventDropDir = s.dir.dropInEvents + ke + '/' + mid + '/'
|
||||
var deleteKey = monitorEventDropDir + firstDroppedPart
|
||||
onFileOrFolderFound(monitorEventDropDir + firstDroppedPart,deleteKey,Object.assign({},s.group[ke].rawMonitorConfigurations[mid]))
|
||||
})
|
||||
resolve({root: s.dir.dropInEvents + user.ke})
|
||||
}else{
|
||||
// reject(new Error('Failed Authorization'))
|
||||
}
|
||||
})
|
||||
})
|
||||
ftpServer.on('client-error', ({connection, context, error}) => {
|
||||
console.log('client-error',error)
|
||||
})
|
||||
ftpServer.listen().then(() => {
|
||||
s.systemLog(`FTP Server running on port ${config.ftpServerPort}...`)
|
||||
}).catch(function(err){
|
||||
s.systemLog(err)
|
||||
})
|
||||
}catch(err){
|
||||
console.error(err.message)
|
||||
console.error('Could not start FTP Server, please run "npm install ftp-srv" inside the Shinobi folder.')
|
||||
console.error('The ftp-srv Module is known to have possible vulnerabilities. Due to the nature of the vulnerability you should be unaffected unless the FTP Port is public facing. Use at your own risk.')
|
||||
}
|
||||
}
|
||||
//add extensions
|
||||
s.onMonitorInit(onMonitorInit)
|
||||
|
|
|
@ -20,8 +20,10 @@ module.exports = function(s,config,lang,getSnapshot){
|
|||
|
||||
//telegram bot
|
||||
if(config.telegramBot === true){
|
||||
const TelegramBot = require('node-telegram-bot-api');
|
||||
try{
|
||||
const TelegramBot = require('node-telegram-bot-api');
|
||||
console.error('WARNING : Telegram bot is enabled.')
|
||||
|
||||
const sendMessage = async function(sendBody,attachments,groupKey){
|
||||
var bot = s.group[groupKey].telegramBot
|
||||
if(!bot){
|
||||
|
@ -363,8 +365,9 @@ module.exports = function(s,config,lang,getSnapshot){
|
|||
]
|
||||
})
|
||||
}catch(err){
|
||||
console.error(err)
|
||||
console.log('Could not start Telegram bot, please run "npm install node-telegram-bot-api" inside the Shinobi folder.')
|
||||
console.error(err.message)
|
||||
console.error('Could not start Telegram bot, please run "npm install node-telegram-bot-api" inside the Shinobi folder.')
|
||||
console.error('The Telegram Module is known to have possible vulnerabilities. Use at your own risk.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const fs = require('fs');
|
||||
const { Readable } = require('stream');
|
||||
const B2 = require('backblaze-b2')
|
||||
const B2 = require('shinobi-backblaze-b2')
|
||||
module.exports = function(s,config,lang){
|
||||
//Backblaze B2
|
||||
var serviceProvider = 'b2'
|
||||
|
|
|
@ -1,356 +1,372 @@
|
|||
var fs = require('fs');
|
||||
var webdav = require("webdav-fs");
|
||||
module.exports = function(s,config,lang){
|
||||
// WebDAV
|
||||
var beforeAccountSaveForWebDav = function(d){
|
||||
//d = save event
|
||||
d.formDetails.webdav_use_global=d.d.webdav_use_global
|
||||
d.formDetails.use_webdav=d.d.use_webdav
|
||||
}
|
||||
var cloudDiskUseStartupForWebDav = function(group,userDetails){
|
||||
group.cloudDiskUse['webdav'].name = 'WebDAV'
|
||||
group.cloudDiskUse['webdav'].sizeLimitCheck = (userDetails.use_webdav_size_limit === '1')
|
||||
if(!userDetails.webdav_size_limit || userDetails.webdav_size_limit === ''){
|
||||
group.cloudDiskUse['webdav'].sizeLimit = 10000
|
||||
}else{
|
||||
group.cloudDiskUse['webdav'].sizeLimit = parseFloat(userDetails.webdav_size_limit)
|
||||
}
|
||||
}
|
||||
var loadWebDavForUser = function(e){
|
||||
// e = user
|
||||
var userDetails = JSON.parse(e.details);
|
||||
if(userDetails.webdav_use_global === '1' && config.cloudUploaders && config.cloudUploaders.WebDAV){
|
||||
// {
|
||||
// webdav_user: "",
|
||||
// webdav_pass: "",
|
||||
// webdav_url: "",
|
||||
// webdav_dir: "",
|
||||
// }
|
||||
userDetails = Object.assign(userDetails,config.cloudUploaders.WebDAV)
|
||||
}
|
||||
//owncloud/webdav
|
||||
if(!s.group[e.ke].webdav &&
|
||||
userDetails.webdav_user&&
|
||||
userDetails.webdav_user!==''&&
|
||||
userDetails.webdav_pass&&
|
||||
userDetails.webdav_pass!==''&&
|
||||
userDetails.webdav_url&&
|
||||
userDetails.webdav_url!==''
|
||||
){
|
||||
if(!userDetails.webdav_dir||userDetails.webdav_dir===''){
|
||||
userDetails.webdav_dir='/'
|
||||
}
|
||||
userDetails.webdav_dir = s.checkCorrectPathEnding(userDetails.webdav_dir)
|
||||
s.group[e.ke].webdav = webdav.createAdapter(userDetails.webdav_url, {
|
||||
username: userDetails.webdav_user,
|
||||
password: userDetails.webdav_pass
|
||||
})
|
||||
}
|
||||
}
|
||||
var unloadWebDavForUser = function(user){
|
||||
s.group[user.ke].webdav = null
|
||||
}
|
||||
var deleteVideoFromWebDav = function(groupKey,video,callback){
|
||||
// e = user
|
||||
module.exports = async function(s,config,lang){
|
||||
if(config.webDavUpload){
|
||||
try{
|
||||
var videoDetails = JSON.parse(video.details)
|
||||
}catch(err){
|
||||
var videoDetails = video.details
|
||||
}
|
||||
if(video.type !== 'webdav'){
|
||||
callback()
|
||||
return
|
||||
}
|
||||
if(!videoDetails.location){
|
||||
var prefix = s.addUserPassToUrl(s.checkCorrectPathEnding(s.group[groupKey].init.webdav_url),s.group[groupKey].init.webdav_user,s.group[groupKey].init.webdav_pass)
|
||||
videoDetails.location = video.href.replace(prefix,'')
|
||||
}
|
||||
s.group[groupKey].webdav.unlink(videoDetails.location, function(err) {
|
||||
if (err) console.log(videoDetails.location,err)
|
||||
callback()
|
||||
})
|
||||
}
|
||||
var uploadVideoToWebDav = function(e,k){
|
||||
//e = video object
|
||||
//k = temporary values
|
||||
if(!k)k={};
|
||||
//cloud saver - webdav
|
||||
var wfs = s.group[e.ke].webdav
|
||||
if(wfs && s.group[e.ke].init.use_webdav !== '0' && s.group[e.ke].init.webdav_save === "1"){
|
||||
var webdavUploadDir = s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/'
|
||||
var startWebDavUpload = function(){
|
||||
s.group[e.ke].activeMonitors[e.id].webdavDirExist = true
|
||||
var wfsWriteStream =
|
||||
fs.createReadStream(k.dir + k.filename).pipe(wfs.createWriteStream(webdavUploadDir + k.filename))
|
||||
if(s.group[e.ke].init.webdav_log === '1'){
|
||||
var webdavRemoteUrl = s.addUserPassToUrl(s.checkCorrectPathEnding(s.group[e.ke].init.webdav_url),s.group[e.ke].init.webdav_user,s.group[e.ke].init.webdav_pass) + s.group[e.ke].init.webdav_dir + e.ke + '/'+e.mid+'/'+k.filename
|
||||
s.knexQuery({
|
||||
action: "insert",
|
||||
table: "Cloud Videos",
|
||||
insert: {
|
||||
mid: e.mid,
|
||||
ke: e.ke,
|
||||
time: k.startTime,
|
||||
status: 1,
|
||||
type : 'webdav',
|
||||
details: s.s({
|
||||
location : webdavUploadDir + k.filename
|
||||
}),
|
||||
size: k.filesize,
|
||||
end: k.endTime,
|
||||
href: ''
|
||||
}
|
||||
})
|
||||
s.setCloudDiskUsedForGroup(e.ke,{
|
||||
amount: k.filesizeMB,
|
||||
storageType: 'webdav'
|
||||
})
|
||||
s.purgeCloudDiskForGroup(e,'webdav')
|
||||
}
|
||||
}
|
||||
if(s.group[e.ke].activeMonitors[e.id].webdavDirExist !== true){
|
||||
//check if webdav dir exist
|
||||
var parentPoint = 0
|
||||
var webDavParentz = webdavUploadDir.split('/')
|
||||
var webDavParents = []
|
||||
webDavParentz.forEach(function(v){
|
||||
if(v && v !== '')webDavParents.push(v)
|
||||
})
|
||||
var stitchPieces = './'
|
||||
var lastParentCheck = function(){
|
||||
++parentPoint
|
||||
if(parentPoint === webDavParents.length){
|
||||
startWebDavUpload()
|
||||
}
|
||||
checkPathPiece(webDavParents[parentPoint])
|
||||
}
|
||||
var checkPathPiece = function(pathPiece){
|
||||
if(pathPiece && pathPiece !== ''){
|
||||
stitchPieces += pathPiece + '/'
|
||||
wfs.stat(stitchPieces, function(error, stats) {
|
||||
if(error){
|
||||
reply = {
|
||||
status : error.status,
|
||||
msg : lang.WebdavErrorTextTryCreatingDir,
|
||||
dir : stitchPieces,
|
||||
const webdav = await import("webdav-fs");
|
||||
console.error('WARNING : WebDAV is enabled.')
|
||||
// WebDAV
|
||||
var beforeAccountSaveForWebDav = function(d){
|
||||
//d = save event
|
||||
d.formDetails.webdav_use_global=d.d.webdav_use_global
|
||||
d.formDetails.use_webdav=d.d.use_webdav
|
||||
}
|
||||
var cloudDiskUseStartupForWebDav = function(group,userDetails){
|
||||
group.cloudDiskUse['webdav'].name = 'WebDAV'
|
||||
group.cloudDiskUse['webdav'].sizeLimitCheck = (userDetails.use_webdav_size_limit === '1')
|
||||
if(!userDetails.webdav_size_limit || userDetails.webdav_size_limit === ''){
|
||||
group.cloudDiskUse['webdav'].sizeLimit = 10000
|
||||
}else{
|
||||
group.cloudDiskUse['webdav'].sizeLimit = parseFloat(userDetails.webdav_size_limit)
|
||||
}
|
||||
}
|
||||
var loadWebDavForUser = function(e){
|
||||
// e = user
|
||||
var userDetails = JSON.parse(e.details);
|
||||
if(userDetails.webdav_use_global === '1' && config.cloudUploaders && config.cloudUploaders.WebDAV){
|
||||
// {
|
||||
// webdav_user: "",
|
||||
// webdav_pass: "",
|
||||
// webdav_url: "",
|
||||
// webdav_dir: "",
|
||||
// }
|
||||
userDetails = Object.assign(userDetails,config.cloudUploaders.WebDAV)
|
||||
}
|
||||
//owncloud/webdav
|
||||
if(!s.group[e.ke].webdav &&
|
||||
userDetails.webdav_user&&
|
||||
userDetails.webdav_user!==''&&
|
||||
userDetails.webdav_pass&&
|
||||
userDetails.webdav_pass!==''&&
|
||||
userDetails.webdav_url&&
|
||||
userDetails.webdav_url!==''
|
||||
){
|
||||
if(!userDetails.webdav_dir||userDetails.webdav_dir===''){
|
||||
userDetails.webdav_dir='/'
|
||||
}
|
||||
userDetails.webdav_dir = s.checkCorrectPathEnding(userDetails.webdav_dir)
|
||||
s.group[e.ke].webdav = webdav.createAdapter(userDetails.webdav_url, {
|
||||
username: userDetails.webdav_user,
|
||||
password: userDetails.webdav_pass
|
||||
})
|
||||
}
|
||||
}
|
||||
var unloadWebDavForUser = function(user){
|
||||
s.group[user.ke].webdav = null
|
||||
}
|
||||
var deleteVideoFromWebDav = function(groupKey,video,callback){
|
||||
// e = user
|
||||
try{
|
||||
var videoDetails = JSON.parse(video.details)
|
||||
}catch(err){
|
||||
var videoDetails = video.details
|
||||
}
|
||||
if(video.type !== 'webdav'){
|
||||
callback()
|
||||
return
|
||||
}
|
||||
if(!videoDetails.location){
|
||||
var prefix = s.addUserPassToUrl(s.checkCorrectPathEnding(s.group[groupKey].init.webdav_url),s.group[groupKey].init.webdav_user,s.group[groupKey].init.webdav_pass)
|
||||
videoDetails.location = video.href.replace(prefix,'')
|
||||
}
|
||||
s.group[groupKey].webdav.unlink(videoDetails.location, function(err) {
|
||||
if (err) console.log(videoDetails.location,err)
|
||||
callback()
|
||||
})
|
||||
}
|
||||
var uploadVideoToWebDav = function(e,k){
|
||||
//e = video object
|
||||
//k = temporary values
|
||||
if(!k)k={};
|
||||
//cloud saver - webdav
|
||||
var wfs = s.group[e.ke].webdav
|
||||
if(wfs && s.group[e.ke].init.use_webdav !== '0' && s.group[e.ke].init.webdav_save === "1"){
|
||||
var webdavUploadDir = s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/'
|
||||
var startWebDavUpload = function(){
|
||||
s.group[e.ke].activeMonitors[e.id].webdavDirExist = true
|
||||
var wfsWriteStream =
|
||||
fs.createReadStream(k.dir + k.filename).pipe(wfs.createWriteStream(webdavUploadDir + k.filename))
|
||||
if(s.group[e.ke].init.webdav_log === '1'){
|
||||
var webdavRemoteUrl = s.addUserPassToUrl(s.checkCorrectPathEnding(s.group[e.ke].init.webdav_url),s.group[e.ke].init.webdav_user,s.group[e.ke].init.webdav_pass) + s.group[e.ke].init.webdav_dir + e.ke + '/'+e.mid+'/'+k.filename
|
||||
s.knexQuery({
|
||||
action: "insert",
|
||||
table: "Cloud Videos",
|
||||
insert: {
|
||||
mid: e.mid,
|
||||
ke: e.ke,
|
||||
time: k.startTime,
|
||||
status: 1,
|
||||
type : 'webdav',
|
||||
details: s.s({
|
||||
location : webdavUploadDir + k.filename
|
||||
}),
|
||||
size: k.filesize,
|
||||
end: k.endTime,
|
||||
href: ''
|
||||
}
|
||||
s.userLog(e,{type:lang['Webdav Error'],msg:reply})
|
||||
wfs.mkdir(stitchPieces, function(error) {
|
||||
})
|
||||
s.setCloudDiskUsedForGroup(e.ke,{
|
||||
amount: k.filesizeMB,
|
||||
storageType: 'webdav'
|
||||
})
|
||||
s.purgeCloudDiskForGroup(e,'webdav')
|
||||
}
|
||||
}
|
||||
if(s.group[e.ke].activeMonitors[e.id].webdavDirExist !== true){
|
||||
//check if webdav dir exist
|
||||
var parentPoint = 0
|
||||
var webDavParentz = webdavUploadDir.split('/')
|
||||
var webDavParents = []
|
||||
webDavParentz.forEach(function(v){
|
||||
if(v && v !== '')webDavParents.push(v)
|
||||
})
|
||||
var stitchPieces = './'
|
||||
var lastParentCheck = function(){
|
||||
++parentPoint
|
||||
if(parentPoint === webDavParents.length){
|
||||
startWebDavUpload()
|
||||
}
|
||||
checkPathPiece(webDavParents[parentPoint])
|
||||
}
|
||||
var checkPathPiece = function(pathPiece){
|
||||
if(pathPiece && pathPiece !== ''){
|
||||
stitchPieces += pathPiece + '/'
|
||||
wfs.stat(stitchPieces, function(error, stats) {
|
||||
if(error){
|
||||
reply = {
|
||||
status : error.status,
|
||||
msg : lang.WebdavErrorTextCreatingDir,
|
||||
msg : lang.WebdavErrorTextTryCreatingDir,
|
||||
dir : stitchPieces,
|
||||
}
|
||||
s.userLog(e,{type:lang['Webdav Error'],msg:reply})
|
||||
wfs.mkdir(stitchPieces, function(error) {
|
||||
if(error){
|
||||
reply = {
|
||||
status : error.status,
|
||||
msg : lang.WebdavErrorTextCreatingDir,
|
||||
dir : stitchPieces,
|
||||
}
|
||||
s.userLog(e,{type:lang['Webdav Error'],msg:reply})
|
||||
}else{
|
||||
lastParentCheck()
|
||||
}
|
||||
})
|
||||
}else{
|
||||
lastParentCheck()
|
||||
}
|
||||
})
|
||||
}else{
|
||||
lastParentCheck()
|
||||
++parentPoint
|
||||
}
|
||||
})
|
||||
}
|
||||
checkPathPiece(webDavParents[0])
|
||||
}else{
|
||||
++parentPoint
|
||||
startWebDavUpload()
|
||||
}
|
||||
}
|
||||
checkPathPiece(webDavParents[0])
|
||||
}else{
|
||||
startWebDavUpload()
|
||||
}
|
||||
}
|
||||
}
|
||||
function onInsertTimelapseFrame(monitorObject,queryInfo,filePath){
|
||||
var e = monitorObject
|
||||
if(s.group[e.ke].webdav && s.group[e.ke].init.use_webdav !== '0' && s.group[e.ke].init.webdav_save === '1'){
|
||||
const wfs = s.group[e.ke].webdav
|
||||
const saveLocation = s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'_timelapse/' + queryInfo.filename
|
||||
fs.createReadStream(filePath).pipe(wfs.createWriteStream(saveLocation))
|
||||
if(s.group[e.ke].init.webdav_log === '1'){
|
||||
s.knexQuery({
|
||||
action: "insert",
|
||||
table: "Cloud Timelapse Frames",
|
||||
insert: {
|
||||
mid: queryInfo.mid,
|
||||
ke: queryInfo.ke,
|
||||
time: queryInfo.time,
|
||||
filename: queryInfo.filename,
|
||||
type : 'webdav',
|
||||
details: s.s({
|
||||
location : saveLocation
|
||||
}),
|
||||
size: queryInfo.size,
|
||||
href: ''
|
||||
}
|
||||
})
|
||||
s.setCloudDiskUsedForGroup(e.ke,{
|
||||
amount : s.kilobyteToMegabyte(queryInfo.size),
|
||||
storageType : 'webdav'
|
||||
},'timelapseFrames')
|
||||
s.purgeCloudDiskForGroup(e,'webdav','timelapseFrames')
|
||||
}
|
||||
}
|
||||
}
|
||||
function onDeleteTimelapseFrameFromCloud(e,frame,callback){
|
||||
// e = user
|
||||
try{
|
||||
var frameDetails = JSON.parse(frame.details)
|
||||
}catch(err){
|
||||
var frameDetails = frame.details
|
||||
}
|
||||
if(frame.type !== 'webdav'){
|
||||
callback()
|
||||
return
|
||||
}
|
||||
if(!frameDetails.location){
|
||||
frameDetails.location = frame.href.split(locationUrl)[1]
|
||||
}
|
||||
s.group[e.ke].webdav.unlink(frameDetails.location, function(err) {
|
||||
if (err) console.log(frameDetails.location,err)
|
||||
callback()
|
||||
})
|
||||
}
|
||||
async function onGetVideoData(video){
|
||||
const wfs = s.group[video.ke].webdav
|
||||
const videoDetails = s.parseJSON(video.details)
|
||||
const saveLocation = videoDetails.location
|
||||
const fileStream = wfs.createReadStream(saveLocation);
|
||||
return fileStream
|
||||
}
|
||||
//webdav
|
||||
s.addCloudUploader({
|
||||
name: 'webdav',
|
||||
loadGroupAppExtender: loadWebDavForUser,
|
||||
unloadGroupAppExtender: unloadWebDavForUser,
|
||||
insertCompletedVideoExtender: uploadVideoToWebDav,
|
||||
deleteVideoFromCloudExtensions: deleteVideoFromWebDav,
|
||||
cloudDiskUseStartupExtensions: cloudDiskUseStartupForWebDav,
|
||||
beforeAccountSave: beforeAccountSaveForWebDav,
|
||||
onAccountSave: cloudDiskUseStartupForWebDav,
|
||||
onInsertTimelapseFrame: () => {},
|
||||
onDeleteTimelapseFrameFromCloud: () => {},
|
||||
onGetVideoData
|
||||
})
|
||||
return {
|
||||
"evaluation": "details.use_webdav !== '0'",
|
||||
"name": lang.WebDAV,
|
||||
"color": "forestgreen",
|
||||
"info": [
|
||||
{
|
||||
"name": "detail=webdav_save",
|
||||
"selector":"autosave_webdav",
|
||||
"field": lang.Autosave,
|
||||
"description": "",
|
||||
"default": lang.No,
|
||||
"example": "",
|
||||
"fieldType": "select",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
function onInsertTimelapseFrame(monitorObject,queryInfo,filePath){
|
||||
var e = monitorObject
|
||||
if(s.group[e.ke].webdav && s.group[e.ke].init.use_webdav !== '0' && s.group[e.ke].init.webdav_save === '1'){
|
||||
const wfs = s.group[e.ke].webdav
|
||||
const saveLocation = s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'_timelapse/' + queryInfo.filename
|
||||
fs.createReadStream(filePath).pipe(wfs.createWriteStream(saveLocation))
|
||||
if(s.group[e.ke].init.webdav_log === '1'){
|
||||
s.knexQuery({
|
||||
action: "insert",
|
||||
table: "Cloud Timelapse Frames",
|
||||
insert: {
|
||||
mid: queryInfo.mid,
|
||||
ke: queryInfo.ke,
|
||||
time: queryInfo.time,
|
||||
filename: queryInfo.filename,
|
||||
type : 'webdav',
|
||||
details: s.s({
|
||||
location : saveLocation
|
||||
}),
|
||||
size: queryInfo.size,
|
||||
href: ''
|
||||
}
|
||||
})
|
||||
s.setCloudDiskUsedForGroup(e.ke,{
|
||||
amount : s.kilobyteToMegabyte(queryInfo.size),
|
||||
storageType : 'webdav'
|
||||
},'timelapseFrames')
|
||||
s.purgeCloudDiskForGroup(e,'webdav','timelapseFrames')
|
||||
}
|
||||
}
|
||||
}
|
||||
function onDeleteTimelapseFrameFromCloud(e,frame,callback){
|
||||
// e = user
|
||||
try{
|
||||
var frameDetails = JSON.parse(frame.details)
|
||||
}catch(err){
|
||||
var frameDetails = frame.details
|
||||
}
|
||||
if(frame.type !== 'webdav'){
|
||||
callback()
|
||||
return
|
||||
}
|
||||
if(!frameDetails.location){
|
||||
frameDetails.location = frame.href.split(locationUrl)[1]
|
||||
}
|
||||
s.group[e.ke].webdav.unlink(frameDetails.location, function(err) {
|
||||
if (err) console.log(frameDetails.location,err)
|
||||
callback()
|
||||
})
|
||||
}
|
||||
async function onGetVideoData(video){
|
||||
const wfs = s.group[video.ke].webdav
|
||||
const videoDetails = s.parseJSON(video.details)
|
||||
const saveLocation = videoDetails.location
|
||||
const fileStream = wfs.createReadStream(saveLocation);
|
||||
return fileStream
|
||||
}
|
||||
//webdav
|
||||
s.addCloudUploader({
|
||||
name: 'webdav',
|
||||
loadGroupAppExtender: loadWebDavForUser,
|
||||
unloadGroupAppExtender: unloadWebDavForUser,
|
||||
insertCompletedVideoExtender: uploadVideoToWebDav,
|
||||
deleteVideoFromCloudExtensions: deleteVideoFromWebDav,
|
||||
cloudDiskUseStartupExtensions: cloudDiskUseStartupForWebDav,
|
||||
beforeAccountSave: beforeAccountSaveForWebDav,
|
||||
onAccountSave: cloudDiskUseStartupForWebDav,
|
||||
onInsertTimelapseFrame: () => {},
|
||||
onDeleteTimelapseFrameFromCloud: () => {},
|
||||
onGetVideoData
|
||||
})
|
||||
return {
|
||||
"evaluation": "details.use_webdav !== '0'",
|
||||
"name": lang.WebDAV,
|
||||
"color": "forestgreen",
|
||||
"info": [
|
||||
{
|
||||
"name": "detail=webdav_save",
|
||||
"selector":"autosave_webdav",
|
||||
"field": lang.Autosave,
|
||||
"description": "",
|
||||
"default": lang.No,
|
||||
"example": "",
|
||||
"fieldType": "select",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"field": lang.URL,
|
||||
"name": "detail=webdav_url",
|
||||
"form-group-class": "autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"field": lang.Username,
|
||||
"name": "detail=webdav_user",
|
||||
"form-group-class": "autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"field": lang.Password,
|
||||
"fieldType": "password",
|
||||
"name": "detail=webdav_pass",
|
||||
"form-group-class": "autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"field": lang.URL,
|
||||
"name": "detail=webdav_url",
|
||||
"form-group-class": "autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"field": lang.Username,
|
||||
"name": "detail=webdav_user",
|
||||
"form-group-class": "autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"field": lang.Password,
|
||||
"fieldType": "password",
|
||||
"name": "detail=webdav_pass",
|
||||
"form-group-class": "autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "detail=webdav_log",
|
||||
"field": lang['Save Links to Database'],
|
||||
"fieldType": "select",
|
||||
"selector": "h_webdavsld",
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
"hidden": true,
|
||||
"name": "detail=webdav_log",
|
||||
"field": lang['Save Links to Database'],
|
||||
"fieldType": "select",
|
||||
"selector": "h_webdavsld",
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "detail=use_webdav_size_limit",
|
||||
"field": lang['Use Max Storage Amount'],
|
||||
"fieldType": "select",
|
||||
"selector": "h_webdavzl",
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"form-group-class-pre-layer":"h_webdavsld_input h_webdavsld_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "detail=webdav_size_limit",
|
||||
"field": lang['Max Storage Amount'],
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"form-group-class-pre-layer":"h_webdavsld_input h_webdavsld_1",
|
||||
"description": "",
|
||||
"default": "10000",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "detail=webdav_dir",
|
||||
"field": lang['Save Directory'],
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "/",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
]
|
||||
"hidden": true,
|
||||
"name": "detail=use_webdav_size_limit",
|
||||
"field": lang['Use Max Storage Amount'],
|
||||
"fieldType": "select",
|
||||
"selector": "h_webdavzl",
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"form-group-class-pre-layer":"h_webdavsld_input h_webdavsld_1",
|
||||
"description": "",
|
||||
"default": "",
|
||||
"example": "",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "detail=webdav_size_limit",
|
||||
"field": lang['Max Storage Amount'],
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"form-group-class-pre-layer":"h_webdavsld_input h_webdavsld_1",
|
||||
"description": "",
|
||||
"default": "10000",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "detail=webdav_dir",
|
||||
"field": lang['Save Directory'],
|
||||
"form-group-class":"autosave_webdav_input autosave_webdav_1",
|
||||
"description": "",
|
||||
"default": "/",
|
||||
"example": "",
|
||||
"possible": ""
|
||||
},
|
||||
]
|
||||
}
|
||||
}catch(err){
|
||||
console.error(err.message)
|
||||
console.error('Could not start WebDAV Uploader, please run "npm install webdav-fs" inside the Shinobi folder.')
|
||||
console.error('The webdav-fs Module is known to have possible vulnerabilities. Due to the nature of the vulnerability you should be unaffected unless Shinobi is public facing. Use at your own risk.')
|
||||
}
|
||||
}else{
|
||||
try{
|
||||
const webdav = await import("webdav-fs");
|
||||
console.error('!! Looks like you have webdav-fs installed but its not enabled. Due to a vulnerability with it you now need to add "webDavUpload": true to your conf.json to enable it.')
|
||||
}catch(err){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,6 @@
|
|||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.226.0",
|
||||
"async": "^3.2.2",
|
||||
"backblaze-b2": "^1.7.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"bson": "^4.6.1",
|
||||
"connection-tester": "^0.2.0",
|
||||
|
@ -29,7 +28,6 @@
|
|||
"express-fileupload": "^1.4.0",
|
||||
"form-data": "^4.0.0",
|
||||
"fs-extra": "9.0.1",
|
||||
"ftp-srv": "^4.6.2",
|
||||
"googleapis": "^100.0.0",
|
||||
"http-proxy": "^1.18.1",
|
||||
"jsonfile": "^3.0.1",
|
||||
|
@ -44,7 +42,6 @@
|
|||
"node-abort-controller": "^3.0.1",
|
||||
"node-fetch": "^2.6.7",
|
||||
"node-ssh": "^12.0.4",
|
||||
"node-telegram-bot-api": "^0.65.1",
|
||||
"nodemailer": "^6.7.1",
|
||||
"onvif": "^0.7.1",
|
||||
"pam-diff": "^1.1.0",
|
||||
|
@ -53,6 +50,7 @@
|
|||
"pixel-change": "^1.1.0",
|
||||
"pushover-notifications": "^1.2.2",
|
||||
"sat": "^0.7.1",
|
||||
"shinobi-backblaze-b2": "^1.7.1",
|
||||
"shinobi-node-moving-things-tracker": "^0.9.3",
|
||||
"shinobi-onvif": "0.2.2",
|
||||
"shinobi-sound-detection": "^0.1.13",
|
||||
|
@ -61,8 +59,7 @@
|
|||
"socket.io": "^4.4.1",
|
||||
"socket.io-client": "^4.5.3",
|
||||
"tree-kill": "1.2.2",
|
||||
"unzipper": "0.10.11",
|
||||
"webdav-fs": "^4.0.1"
|
||||
"unzipper": "0.10.11"
|
||||
},
|
||||
"bin": "camera.js",
|
||||
"scripts": {
|
||||
|
|
Loading…
Reference in New Issue