upgrade-sftp-uploader
Moe 2022-08-07 21:26:35 -07:00
commit c4627b3c62
31 changed files with 912 additions and 4410 deletions

View File

@ -7592,31 +7592,37 @@ module.exports = function(s,config,lang){
label: `${lang['Monitor Settings']}`,
pageOpen: 'monitorSettings',
addUl: true,
eval: `!$user.details.sub || $user.details.monitor_create !== 0`,
},
{
icon: 'grav',
label: `${lang['Region Editor']}`,
pageOpen: 'regionEditor',
eval: `!$user.details.sub`,
},
{
icon: 'filter',
label: `${lang['Event Filters']}`,
pageOpen: 'eventFilters',
eval: `!$user.details.sub`,
},
{
icon: 'align-right',
label: `${lang['Monitor States']}`,
pageOpen: 'monitorStates',
eval: `!$user.details.sub`,
},
{
icon: 'clock',
label: `${lang['Schedules']}`,
pageOpen: 'schedules',
eval: `!$user.details.sub`,
},
{
icon: 'exclamation-triangle',
label: `${lang['Logs']}`,
pageOpen: 'logViewer',
eval: `!$user.details.sub || $user.details.view_logs !== 0`,
},
{
divider: true,
@ -7625,6 +7631,7 @@ module.exports = function(s,config,lang){
icon: 'gears',
label: `${lang['Account Settings']}`,
pageOpen: 'accountSettings',
eval: `!$user.details.sub || $user.details.user_change !== 0`,
addUl: true,
},
{
@ -7632,6 +7639,7 @@ module.exports = function(s,config,lang){
label: `${lang.subAccountManager}`,
pageOpen: 'subAccountManager',
addUl: true,
eval: `!$user.details.sub`,
},
{
icon: 'key',
@ -7645,12 +7653,14 @@ module.exports = function(s,config,lang){
icon: 'search',
label: `${lang['ONVIF Scanner']}`,
pageOpen: 'onvifScanner',
addUl:true
addUl:true,
eval: `!$user.details.sub || $user.details.monitor_create !== 0`,
},
{
icon: 'opera',
label: `${lang['ONVIF Device Manager']}`,
pageOpen: 'onvifDeviceManager',
eval: `!$user.details.sub || $user.details.monitor_create !== 0`,
},
{
icon: 'eyedropper',
@ -7662,6 +7672,7 @@ module.exports = function(s,config,lang){
label: `${lang['ShinobiHub']}`,
pageOpen: 'configFinder',
addUl: true,
eval: `!$user.details.sub || $user.details.monitor_create !== 0`,
},
{
divider: true,
@ -8449,32 +8460,62 @@ module.exports = function(s,config,lang){
"Editor": {
noHeader: true,
"color": "grey",
"noDefaultSectionClasses": true,
"box-wrapper-class": "row",
"info": [
{
"name": "mail",
"field": lang.Email,
isFormGroupGroup: true,
"noHeader": true,
"section-pre-class": "col-md-6",
info: [
{
"name": "mail",
"field": lang.Email,
},
{
"name": "pass",
"type": "password",
"fieldType": "password",
"field": lang['Password'],
},
{
"name": "pass_again",
"type": "password",
"fieldType": "password",
"field": lang['Password Again'],
},
{
"fieldType": "btn-group",
"btns": [
{
"fieldType": "btn",
"class": `submit btn-success`,
"btnContent": `${lang['Save']}`,
},
],
},
]
},
{
"name": "pass",
"type": "password",
"fieldType": "password",
"field": lang['Password'],
},
{
"name": "pass_again",
"type": "password",
"fieldType": "password",
"field": lang['Password Again'],
},
{
"fieldType": "btn-group",
"btns": [
{
"fieldType": "btn",
"class": `submit btn-success`,
"btnContent": `${lang['Save']}`,
},
],
isFormGroupGroup: true,
"name": lang["API Keys"],
"section-pre-class": "col-md-6",
info: [
{
"fieldType": "btn-group",
"btns": [
{
"fieldType": "btn",
"class": `new-token btn-success`,
"btnContent": `${lang['Add']}`,
},
],
},
{
"id": "super-tokens",
"fieldType": "div",
},
]
},
]
}

View File

@ -78,24 +78,21 @@ module.exports = function(s,config,lang){
var isSessionKey = false
if(apiKey){
var sessionKey = params.auth
createSession(apiKey,{
auth: sessionKey,
permissions: s.parseJSON(apiKey.details),
details: {}
})
getUserByUid(apiKey,'mail,details',function(err,user){
if(user){
try{
editSession({
auth: sessionKey
},{
mail: user.mail,
details: s.parseJSON(user.details),
lang: s.getLanguageFile(user.details.lang)
})
}catch(er){
console.log('FAILED TO EDIT',er)
}
createSession(apiKey,{
auth: sessionKey,
permissions: s.parseJSON(apiKey.details),
mail: user.mail,
details: s.parseJSON(user.details),
lang: s.getLanguageFile(user.details.lang)
})
}else{
createSession(apiKey,{
auth: sessionKey,
permissions: s.parseJSON(apiKey.details),
details: {}
})
}
callback(err,s.api[params.auth])
})

View File

@ -14,7 +14,7 @@ module.exports = function(s,config,lang,app,io){
if(!config.logoLocation196x196)config.logoLocation196x196 = 'libs/img/icon/favicon-196x196.png';
if(config.logoLocation76x76Link === undefined){config.logoLocation76x76Link='https://shinobi.video'}
if(config.logoLocation76x76Style === undefined){config.logoLocation76x76Style='border-radius:50%'}
if(config.loginScreenBackground === undefined){config.loginScreenBackground='https://shinobi.video/libs/assets/backgrounds/7.jpg'}
if(config.loginScreenBackground === undefined){config.loginScreenBackground='assets/img/splash.avif'}
if(config.showLoginSelector === undefined){config.showLoginSelector=true}
if(config.defaultTheme === undefined)config.defaultTheme = 'Ice-v3';
if(config.socialLinks === undefined){

View File

@ -87,11 +87,11 @@ module.exports = function(s,config){
const knexError = (dbQuery,options,err) => {
console.error('knexError----------------------------------- START')
if(config.debugLogVerbose && config.debugLog === true){
s.debugLog('s.knexQuery QUERY',JSON.stringify(options,null,3))
s.debugLog('STACK TRACE, NOT AN ',new Error())
}
console.error(err)
console.error(dbQuery.toString())
// CANNOT USE `dbQuery.toString()` because it breaks the query
console.error(options)
console.error('knexError----------------------------------- END')
}
const knexQuery = (options,callback) => {
@ -149,7 +149,8 @@ module.exports = function(s,config){
}
}
if(config.debugLog === true){
console.log(dbQuery.toString())
// CANNOT USE `dbQuery.toString()` because it breaks the query
console.log(options)
}
if(callback || options.update || options.insert || options.action === 'delete'){
dbQuery.asCallback(function(err,r) {

View File

@ -215,12 +215,20 @@ module.exports = function(s,config,lang,app,io){
}
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Permitted']
})
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_view`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
s.knexQuery({

View File

@ -1773,6 +1773,7 @@ module.exports = function(s,config,lang){
monitorRestrictions.push(['or','mid','=',v])
}
})
console.log(monitorRestrictions)
}catch(er){
}
}else if(
@ -1790,20 +1791,104 @@ module.exports = function(s,config,lang){
){}
return monitorRestrictions
}
// s.checkViewerConnectionsForMonitor = function(monitorObject){
// var monitorConfig = s.group[monitorObject.ke].rawMonitorConfigurations[monitorObject.mid]
// if(monitorConfig.mode === 'start'){
//
// }
// }
// s.addViewerConnectionForMonitor = function(monitorObject,viewerDetails){
// s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnection[viewerDetails.viewerId] = viewerDetails
// s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount += 1
// return s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount
// }
// s.removeViewerConnectionForMonitor = function(monitorObject,viewerDetails){
// delete(s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnection[viewerDetails.viewerId])
// s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount -= 1
// return s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount
// }
s.checkPermission = (user) => {
// provide "user" object given from "s.auth"
const isSubAccount = !!user.details.sub
const response = {
isSubAccount,
hasAllPermissions: isSubAccount && user.details.allmonitors === '1',
isRestricted: isSubAccount && user.details.allmonitors !== '1',
isRestrictedApiKey: false,
apiKeyPermissions: {},
userPermissions: {},
}
const permissions = user.permissions
const details = user.details;
[
'auth_socket',
'get_monitors',
'control_monitors',
'get_logs',
'watch_stream',
'watch_snapshot',
'watch_videos',
'delete_videos',
].forEach((key) => {
const permissionOff = permissions[key] === '0';
response.apiKeyPermissions[key] = permissions[key] === '1';
response.apiKeyPermissions[`${key}_disallowed`] = permissionOff;
response.isRestrictedApiKey = response.isRestrictedApiKey || permissionOff;
});
// Base Level Permissions
// allmonitors : All Monitors and Privileges
// monitor_create : Can Create and Delete Monitors
// user_change : Can Change User Settings
// view_logs : Can View Logs
[
'allmonitors',
'monitor_create',
'user_change',
'view_logs',
].forEach((key) => {
response.userPermissions[key] = details[key] === '1' || !details[key];
response.userPermissions[`${key}_disallowed`] = details[key] === '0';
});
return response
}
s.getMonitorsPermitted = (userDetails,monitorId) => {
const monitorRestrictions = []
const monitors = {}
function setMonitorPermissions(mid){
// monitors : Can View Monitor
// monitor_edit : Can Edit Monitor (Delete as well)
// video_view : Can View Videos and Events
// video_delete : Can Delete Videos and Events
[
'monitors',
'monitor_edit',
'video_view',
'video_delete',
].forEach((key) => {
monitors[`${mid}_${key}`] = userDetails[key] && userDetails[key].indexOf(mid) > -1 || false;
});
return true
}
function addToQuery(mid,n){
if(n === 0){
monitorRestrictions.push(['mid','=',mid])
}else{
monitorRestrictions.push(['or','mid','=',mid])
}
};
if(
!monitorId &&
userDetails.sub &&
userDetails.monitors &&
userDetails.allmonitors !== '1'
){
try{
userDetails.monitors = s.parseJSON(userDetails.monitors)
userDetails.monitors.forEach(function(v,n){
setMonitorPermissions(v)
addToQuery(v,n)
})
}catch(err){
s.debugLog(err)
}
}else if(
monitorId && (
!userDetails.sub ||
userDetails.allmonitors !== '0' ||
userDetails.monitors.indexOf(monitorId) >- 1
)
){
setMonitorPermissions(monitorId)
addToQuery(monitorId,0)
}
return {
monitorPermissions: monitors,
// queryConditions
monitorRestrictions: monitorRestrictions,
}
}
}

View File

@ -26,10 +26,26 @@ module.exports = function(s,config,lang,app,io){
*/
app.get(config.webPaths.apiPrefix+':auth/onvifDeviceManager/:ke/:id',function (req,res){
s.auth(req.params,async (user) => {
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.get_monitors_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_monitors`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
const endData = {ok: true}
try{
const groupKey = req.params.ke
const monitorId = req.params.id
const onvifDevice = await getOnvifDevice(groupKey,monitorId)
const cameraInfo = await getUIFieldValues(onvifDevice)
endData.onvifData = cameraInfo
@ -46,11 +62,29 @@ module.exports = function(s,config,lang,app,io){
*/
app.post(config.webPaths.apiPrefix+':auth/onvifDeviceManager/:ke/:id/save',function (req,res){
s.auth(req.params,async (user) => {
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId);
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed
){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Authorized']
});
return
}
const endData = {ok: true}
const responses = {}
try{
const groupKey = req.params.ke
const monitorId = req.params.id
const onvifDevice = await getOnvifDevice(groupKey,monitorId)
const form = s.getPostData(req)
const videoToken = form.VideoConfiguration && form.VideoConfiguration.videoToken ? form.VideoConfiguration.videoToken : null
@ -100,10 +134,28 @@ module.exports = function(s,config,lang,app,io){
*/
app.get(config.webPaths.apiPrefix+':auth/onvifDeviceManager/:ke/:id/reboot',function (req,res){
s.auth(req.params,async (user) => {
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId);
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed
){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Authorized']
});
return
}
const endData = {ok: true}
try{
const groupKey = req.params.ke
const monitorId = req.params.id
const onvifDevice = await getOnvifDevice(groupKey,monitorId)
const cameraInfo = await rebootCamera(onvifDevice)
endData.onvifData = cameraInfo

View File

@ -21,6 +21,20 @@ module.exports = function(s,config,lang,app,io){
*/
app.get(config.webPaths.apiPrefix+':auth/probe/:ke',function (req,res){
s.auth(req.params,function(user){
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed
){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Authorized']
});
return
}
ffprobe(req.query.url,req.params.auth,(endData) => {
s.closeJsonResponse(res,endData)
})

View File

@ -194,9 +194,11 @@ module.exports = function(s,config,lang,app,io){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const {
isSubAccount,
} = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return
}
var whereQuery = [
@ -234,9 +236,11 @@ module.exports = function(s,config,lang,app,io){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const {
isSubAccount,
} = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return
}
switch(req.params.action){

View File

@ -431,19 +431,27 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
var hasRestrictions = user.details.sub && user.details.allmonitors !== '1'
const monitorId = req.params.id
const groupKey = req.params.ke
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
user.permissions.watch_videos==="0" ||
hasRestrictions &&
(
!user.details.video_view ||
user.details.video_view.indexOf(req.params.id) === -1
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_video_view`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,[])
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], frames: []});
return
}
const monitorRestrictions = s.getMonitorRestrictions(user.details,req.params.id)
s.getDatabaseRows({
monitorRestrictions: monitorRestrictions,
table: 'Timelapse Frames',
@ -474,23 +482,21 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,function(user){
const groupKey = req.params.ke
const monitorId = req.params.id
var hasRestrictions = user.details.sub && user.details.allmonitors !== '1'
const actionParameter = !!req.params.action
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
user.permissions.watch_videos==="0" ||
hasRestrictions &&
(
!user.details.video_view ||
user.details.video_view.indexOf(req.params.id) === -1
)
isRestrictedApiKey && apiKeyPermissions.delete_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_delete`]
){
s.closeJsonResponse(res,[])
return
}
const monitorRestrictions = s.getMonitorRestrictions(user.details,req.params.id)
if(monitorRestrictions.length === 0){
s.closeJsonResponse(res,{
ok: false
})
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
const framesPerSecond = s.getPostData(req, 'fps')
@ -514,15 +520,31 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
var hasRestrictions = user.details.sub && user.details.allmonitors !== '1'
const groupKey = req.params.ke
const monitorId = req.params.id
const actionParameter = !!req.params.action
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
user.permissions.watch_videos==="0" ||
hasRestrictions && (!user.details.video_view || user.details.video_view.indexOf(req.params.id)===-1)
actionParameter && (
isRestrictedApiKey && apiKeyPermissions.delete_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_delete`]
) ||
!actionParameter && (
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && monitorId && !monitorPermissions[`${monitorId}_video_view`]
)
){
res.end(s.prettyPrint([]))
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
const monitorRestrictions = s.getMonitorRestrictions(user.details,req.params.id)
const cacheKey = req.params.ke + req.params.id + req.params.filename
const processFrame = (frame) => {
var fileLocation
@ -536,7 +558,7 @@ module.exports = function(s,config,lang,app,io){
selectedDate = req.params.filename.split('T')[0]
}
fileLocation = `${fileLocation}${frame.ke}/${frame.mid}_timelapse/${selectedDate}/${req.params.filename}`
if(req.params.action === 'delete'){
if(actionParameter === 'delete'){
deleteTimelapseFrame({
ke: frame.ke,
mid: frame.mid,

View File

@ -16,9 +16,11 @@ module.exports = function(s,config,lang,app){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const {
isSubAccount,
} = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return
}
var form = s.getPostData(req)
@ -103,9 +105,11 @@ module.exports = function(s,config,lang,app){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const {
isSubAccount,
} = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return
}
var form = s.getPostData(req) || {}
@ -174,9 +178,11 @@ module.exports = function(s,config,lang,app){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const {
isSubAccount,
} = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return
}else{
endData.ok = true
@ -209,9 +215,11 @@ module.exports = function(s,config,lang,app){
}
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
if(user.details.sub){
endData.msg = user.lang['Not an Administrator Account']
s.closeJsonResponse(res,endData)
const {
isSubAccount,
} = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return
}
var form = s.getPostData(req)
@ -290,7 +298,26 @@ module.exports = function(s,config,lang,app){
}
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
var hasRestrictions = user.details.sub && user.details.allmonitors !== '1'
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
userPermissions,
} = s.checkPermission(user)
if(
userPermissions.monitor_create_disallowed ||
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_monitor_edit`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
if(req.params.f !== 'delete'){
var form = s.getPostData(req)
if(!form){
@ -299,66 +326,46 @@ module.exports = function(s,config,lang,app){
return
}
form.mid = req.params.id.replace(/[^\w\s]/gi,'').replace(/ /g,'')
if(!user.details.sub ||
user.details.allmonitors === '1' ||
hasRestrictions && user.details.monitor_edit.indexOf(form.mid) >- 1 ||
hasRestrictions && user.details.monitor_create === '1'){
if(form && form.name){
s.checkDetails(form)
form.ke = req.params.ke
s.addOrEditMonitor(form,function(err,endData){
res.end(s.prettyPrint(endData))
},user)
}else{
endData.msg = user.lang.monitorEditText1;
res.end(s.prettyPrint(endData))
}
}else{
endData.msg = user.lang['Not Permitted']
if(form && form.name){
s.checkDetails(form)
form.ke = req.params.ke
s.addOrEditMonitor(form,function(err,endData){
res.end(s.prettyPrint(endData))
},user)
}else{
endData.msg = user.lang.monitorEditText1;
res.end(s.prettyPrint(endData))
}
}else{
if(!user.details.sub || user.details.allmonitors === '1' || user.details.monitor_edit.indexOf(req.params.id) > -1 || hasRestrictions && user.details.monitor_create === '1'){
s.userLog({
s.userLog({
ke: req.params.ke,
mid: req.params.id
},{
type: 'Monitor Deleted',
msg: 'by user : '+user.uid
});
req.params.delete=1;
s.camera('stop',req.params);
s.tx({f:'monitor_delete',uid:user.uid,mid:req.params.id,ke:req.params.ke},'GRP_'+req.params.ke);
s.knexQuery({
action: "delete",
table: "Monitors",
where: {
ke: req.params.ke,
mid: req.params.id
},{
type: 'Monitor Deleted',
msg: 'by user : '+user.uid
});
req.params.delete=1;s.camera('stop',req.params);
s.tx({f:'monitor_delete',uid:user.uid,mid:req.params.id,ke:req.params.ke},'GRP_'+req.params.ke);
s.knexQuery({
action: "delete",
table: "Monitors",
where: {
mid: req.params.id,
}
})
if(req.query.deleteFiles === 'true'){
deleteMonitorData(req.params.ke,req.params.id).then(() => {
s.debugLog(`Deleted Monitor Data`,{
ke: req.params.ke,
mid: req.params.id,
}
})
// s.knexQuery({
// action: "delete",
// table: "Files",
// where: {
// ke: req.params.ke,
// mid: req.params.id,
// }
// })
if(req.query.deleteFiles === 'true'){
deleteMonitorData(req.params.ke,req.params.id).then(() => {
s.debugLog(`Deleted Monitor Data`,{
ke: req.params.ke,
mid: req.params.id,
})
})
}
endData.ok=true;
endData.msg='Monitor Deleted by user : '+user.uid
res.end(s.prettyPrint(endData))
}else{
endData.msg=user.lang['Not Permitted'];
res.end(s.prettyPrint(endData))
})
}
endData.ok=true;
endData.msg='Monitor Deleted by user : '+user.uid
res.end(s.prettyPrint(endData))
}
},res,req)
})
@ -509,9 +516,18 @@ module.exports = function(s,config,lang,app){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const groupKey = req.params.ke
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
userPermissions,
} = s.checkPermission(user)
if(
userPermissions.monitor_create_disallowed ||
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
s.knexQuery({
@ -547,9 +563,18 @@ module.exports = function(s,config,lang,app){
var endData = {
ok : false
}
if(user.details.sub){
endData.msg = user.lang['Not Permitted']
s.closeJsonResponse(res,endData)
const groupKey = req.params.ke
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
userPermissions,
} = s.checkPermission(user)
if(
userPermissions.monitor_create_disallowed ||
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
var presetQueryVals = [req.params.ke,'monitorStates',req.params.stateName]

View File

@ -647,8 +647,22 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,function(user){
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.get_monitors_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_monitors`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,[]);
return
}
@ -752,8 +766,22 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,(user) => {
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.get_monitors_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_monitors`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,[]);
return
}
@ -831,11 +859,19 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,async (user) => {
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
userPermissions,
apiKeyPermissions,
isRestrictedApiKey,
} = s.checkPermission(user)
if(
user.permissions.control_monitors === "0" ||
user.details.sub &&
user.details.allmonitors !== '1' &&
user.details.monitor_edit.indexOf(monitorId) === -1
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_monitor_edit`]
){
response.msg = user.lang['Not Permitted']
}else{
@ -860,64 +896,64 @@ module.exports = function(s,config,lang,app,io){
s.closeJsonResponse(res,response);
},res,req);
});
/**
* API : Merge Recorded Videos into one file
*/
app.get(config.webPaths.apiPrefix+':auth/videosMerge/:ke', function (req,res){
var failed = function(resp){
res.setHeader('Content-Type', 'application/json');
res.end(s.prettyPrint(resp))
}
if(req.query.videos && req.query.videos !== ''){
s.auth(req.params,function(user){
var videosSelected = JSON.parse(req.query.videos)
const whereQuery = []
var didOne = false
videosSelected.forEach(function(video){
var time = s.nameToTime(video.filename)
if(req.query.isUTC === 'true'){
time = s.utcToLocal(time)
}
if(didOne){
whereQuery.push(['or','ke','=',req.params.ke])
}else{
didOne = true
whereQuery.push(['ke','=',req.params.ke])
}
whereQuery.push(
['mid','=',video.mid],
['time','=',time],
)
})
s.knexQuery({
action: "select",
columns: "*",
table: "Videos",
where: whereQuery
},(err,r) => {
var resp = {ok: false}
if(r && r[0]){
s.mergeRecordedVideos(r,req.params.ke,function(fullPath,filename){
res.setHeader('Content-Disposition', 'attachment; filename="'+filename+'"')
var file = fs.createReadStream(fullPath)
file.on('close',function(){
setTimeout(function(){
s.file('delete',fullPath)
},1000 * 60 * 3)
res.end()
})
file.pipe(res)
})
}else{
failed({ok:false,msg:'No Videos Found'})
}
})
},res,req);
}else{
failed({ok:false,msg:'"videos" query variable is missing from request.'})
}
})
// /**
// * API : Merge Recorded Videos into one file
// */
// app.get(config.webPaths.apiPrefix+':auth/videosMerge/:ke', function (req,res){
// var failed = function(resp){
// res.setHeader('Content-Type', 'application/json');
// res.end(s.prettyPrint(resp))
// }
// if(req.query.videos && req.query.videos !== ''){
// s.auth(req.params,function(user){
// var videosSelected = JSON.parse(req.query.videos)
// const whereQuery = []
// var didOne = false
// videosSelected.forEach(function(video){
// var time = s.nameToTime(video.filename)
// if(req.query.isUTC === 'true'){
// time = s.utcToLocal(time)
// }
// if(didOne){
// whereQuery.push(['or','ke','=',req.params.ke])
// }else{
// didOne = true
// whereQuery.push(['ke','=',req.params.ke])
// }
// whereQuery.push(
// ['mid','=',video.mid],
// ['time','=',time],
// )
//
// })
// s.knexQuery({
// action: "select",
// columns: "*",
// table: "Videos",
// where: whereQuery
// },(err,r) => {
// var resp = {ok: false}
// if(r && r[0]){
// s.mergeRecordedVideos(r,req.params.ke,function(fullPath,filename){
// res.setHeader('Content-Disposition', 'attachment; filename="'+filename+'"')
// var file = fs.createReadStream(fullPath)
// file.on('close',function(){
// setTimeout(function(){
// s.file('delete',fullPath)
// },1000 * 60 * 3)
// res.end()
// })
// file.pipe(res)
// })
// }else{
// failed({ok:false,msg:'No Videos Found'})
// }
// })
// },res,req);
// }else{
// failed({ok:false,msg:'"videos" query variable is missing from request.'})
// }
// })
/**
* API : Get Videos
*/
@ -929,10 +965,27 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id
const groupKey = req.params.ke
const hasRestrictions = userDetails.sub && userDetails.allmonitors !== '1';
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_video_view`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], videos: []});
return
}
var origURL = req.originalUrl.split('/')
var videoParam = origURL[origURL.indexOf(req.params.auth) + 1]
var videoSet = 'Videos'
@ -957,11 +1010,7 @@ module.exports = function(s,config,lang,app,io){
endIsStartTo: !!req.query.endIsStartTo,
parseRowDetails: false,
rowName: 'videos',
preliminaryValidationFailed: (
user.permissions.watch_videos === "0" ||
hasRestrictions &&
(!userDetails.video_view || userDetails.video_view.indexOf(monitorId)===-1)
)
preliminaryValidationFailed: false
},(response) => {
if(response && response.videos){
s.buildVideoLinks(response.videos,{
@ -986,10 +1035,27 @@ module.exports = function(s,config,lang,app,io){
const searchQuery = s.getPostData(req,'search')
const startTime = s.getPostData(req,'start')
const endTime = s.getPostData(req,'end')
const userDetails = user.details
const monitorId = req.params.id
const groupKey = req.params.ke
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_video_view`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], videos: []});
return
}
getVideosBasedOnTagFoundInMatrixOfAssociatedEvent({
groupKey,
monitorId,
@ -1020,17 +1086,28 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id
const groupKey = req.params.ke
const hasRestrictions = userDetails.sub && userDetails.allmonitors !== '1';
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
const preliminaryValidationFailed = (
user.permissions.watch_videos === "0" ||
hasRestrictions &&
(!userDetails.video_view || userDetails.video_view.indexOf(monitorId)===-1)
);
if(req.query.onlyCount === '1' && !preliminaryValidationFailed){
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_video_view`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], events: []});
return
}
if(req.query.onlyCount === '1'){
const response = {ok: true}
s.knexQuery({
action: "count",
@ -1068,7 +1145,7 @@ module.exports = function(s,config,lang,app,io){
noFormat: true,
noCount: true,
rowName: 'events',
preliminaryValidationFailed: preliminaryValidationFailed
preliminaryValidationFailed: false
},(response) => {
res.end(s.prettyPrint(response))
})
@ -1084,10 +1161,21 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id
const groupKey = req.params.ke
const hasRestrictions = userDetails.sub && userDetails.allmonitors !== '1';
const monitorId = req.params.id
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
userPermissions,
} = s.checkPermission(user)
if(
userPermissions.view_logs_disallowed ||
isRestrictedApiKey && apiKeyPermissions.get_logs_disallowed
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], logs: []});
return
}
s.sqlQueryBetweenTimesWithPermissions({
table: 'Logs',
user: user,
@ -1102,9 +1190,7 @@ module.exports = function(s,config,lang,app,io){
noFormat: true,
noCount: true,
rowName: 'logs',
preliminaryValidationFailed: (
user.permissions.get_logs === "0" || userDetails.sub && userDetails.view_logs !== '1'
)
preliminaryValidationFailed: false
},(response) => {
response.forEach(function(v,n){
v.info = JSON.parse(v.info)
@ -1114,51 +1200,30 @@ module.exports = function(s,config,lang,app,io){
},res,req)
})
/**
* API : Get Monitors Online
*/
app.get(config.webPaths.apiPrefix+':auth/smonitor/:ke', function (req,res){
var response = {ok:false};
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,(user) => {
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){
s.closeJsonResponse(res,[]);
return
}
s.knexQuery({
action: "select",
columns: "*",
table: "Monitors",
where: [
['ke','=',groupKey],
monitorRestrictions
]
},(err,r) => {
const startedMonitors = []
r.forEach(function(v){
if(
s.group[groupKey] &&
s.group[groupKey].activeMonitors[v.mid] &&
s.group[groupKey].activeMonitors[v.mid].isStarted === true
){
startedMonitors.push(v)
}
})
s.closeJsonResponse(res,startedMonitors)
})
},res,req);
});
/**
* API : Monitor Mode Controller
*/
app.get([config.webPaths.apiPrefix+':auth/monitor/:ke/:id/:f',config.webPaths.apiPrefix+':auth/monitor/:ke/:id/:f/:ff',config.webPaths.apiPrefix+':auth/monitor/:ke/:id/:f/:ff/:fff'], function (req,res){
var response = {ok:false};
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
if(user.permissions.control_monitors==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitor_edit.indexOf(req.params.id)===-1){
res.end(user.lang['Not Permitted'])
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
userPermissions,
} = s.checkPermission(user)
if(
userPermissions.monitor_create_disallowed ||
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_monitor_edit`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
if(req.params.f===''){response.msg = user.lang.monitorGetText1;res.end(s.prettyPrint(response));return}
@ -1277,12 +1342,20 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,function(user){
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.watch_videos === "0" || monitorRestrictions.length === 0)){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Permitted']
})
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_view`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
var time = s.nameToTime(req.params.file)
@ -1334,12 +1407,20 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,function(user){
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.watch_videos === "0" || monitorRestrictions.length === 0)){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Permitted']
})
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_view`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
var time = s.nameToTime(req.params.file)
@ -1399,26 +1480,35 @@ module.exports = function(s,config,lang,app,io){
*/
app.get(config.webPaths.apiPrefix+':auth/motion/:ke/:id', function (req,res){
s.auth(req.params,function(user){
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId)
if(user.details.sub && user.details.allmonitors === '0' && monitorRestrictions.length === 0){
s.closeJsonResponse(res,{
ok: false,
msg: lang['Not Permitted']
})
return
}
const d = {
const groupKey = req.params.ke
const monitorId = req.params.id
const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId]
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId);
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
!monitorConfig ||
isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed
){
s.closeJsonResponse(res,{
ok: false,
msg: !monitorConfig ? user.lang['Monitor or Key does not exist.'] : lang['Not Authorized']
});
return
}
let simulatedEvent = {
id: req.params.id,
ke: req.params.ke
}
if(req.query.data){
try{
Object.assign(d, {details: s.parseJSON(req.query.data)});
Object.assign(simulatedEvent, {details: s.parseJSON(req.query.data)});
}catch(err){
s.closeJsonResponse(res,{
ok: false,
@ -1428,13 +1518,19 @@ module.exports = function(s,config,lang,app,io){
}
}
// fallback for cameras that doesn't support JSON in query parameters ( i.e Sercom ICamera1000 will fail to save HTTP_Notifications as invalid url)
else if( req.query.plug && req.query.name && req.query.reason && req.query.confidence) {
Object.assign(d, {
else if(req.query.plug && req.query.name && req.query.reason && req.query.confidence) {
const {
plug,
reason,
confidence,
name,
} = req.query;
Object.assign(simulatedEvent,{
details: {
plug: req.query.plug,
reason: req.query.reason,
confidence: req.query.confidence,
name: req.query.name
plug,
reason,
confidence,
name,
}
});
}
@ -1445,51 +1541,21 @@ module.exports = function(s,config,lang,app,io){
})
return
}
if(!d.ke||!d.id||!s.group[d.ke]){
s.closeJsonResponse(res,{
ok: false,
msg: user.lang['No Group with this key exists']
})
return
}
if(!s.group[d.ke].rawMonitorConfigurations[d.id]){
s.closeJsonResponse(res,{
ok: false,
msg: user.lang['Monitor or Key does not exist.']
})
return
}
var details = s.group[d.ke].rawMonitorConfigurations[d.id].details
var detectorHttpApi = details.detector_http_api
var detectorOn = (details.detector === '1')
switch(detectorHttpApi){
case'0':
s.closeJsonResponse(res,{
ok: false,
msg: user.lang['Trigger Blocked']
})
return
break;
case'2':
if(!detectorOn){
s.closeJsonResponse(res,{
ok: false,
msg: user.lang['Trigger Blocked']
})
return
}
break;
case'2':
if(detectorOn){
s.closeJsonResponse(res,{
ok: false,
msg: user.lang['Trigger Blocked']
})
return
}
break;
if(
detectorHttpApi === '0' ||
detectorHttpApi === '2' && !detectorOn ||
detectorHttpApi === '3' && detectorOn
){
s.closeJsonResponse(res,{
ok: false,
msg: user.lang['Trigger Blocked']
})
return;
}
triggerEvent(d)
triggerEvent(simulatedEvent)
s.closeJsonResponse(res,{
ok: true,
msg: user.lang['Trigger Successful']
@ -1512,8 +1578,25 @@ module.exports = function(s,config,lang,app,io){
app.get(config.webPaths.apiPrefix+':auth/eventCountStatus/:ke/:id', function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
res.end(user.lang['Not Permitted'])
const monitorId = req.params.id
const groupKey = req.params.ke
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_video_view`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], counted: 0, tags: []});
return
}
var selectedObject = s.group[req.params.ke].activeMonitors[req.params.id].eventsCounted
@ -1533,10 +1616,27 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){
res.setHeader('Content-Type', 'application/json')
s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id
const groupKey = req.params.ke
var hasRestrictions = userDetails.sub && userDetails.allmonitors !== '1';
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
isRestricted && (
monitorId && !monitorPermissions[`${monitorId}_video_view`] ||
monitorRestrictions.length === 0
)
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized'], videos: []});
return
}
s.sqlQueryBetweenTimesWithPermissions({
table: 'Events Counts',
user: user,
@ -1552,11 +1652,7 @@ module.exports = function(s,config,lang,app,io){
endIsStartTo: !!req.query.endIsStartTo,
parseRowDetails: true,
rowName: 'counts',
preliminaryValidationFailed: (
user.permissions.watch_videos === "0" ||
hasRestrictions &&
(!userDetails.video_view || userDetails.video_view.indexOf(monitorId)===-1)
)
preliminaryValidationFailed: false
},(response) => {
res.end(s.prettyPrint(response))
})
@ -1597,12 +1693,24 @@ module.exports = function(s,config,lang,app,io){
var response = {ok:false}
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_delete.indexOf(req.params.id)===-1){
res.end(user.lang['Not Permitted'])
const groupKey = req.params.ke
const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions.delete_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_delete`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
var groupKey = req.params.ke
var monitorId = req.params.id
// req.query.overwrite === '1'
if(s.group[groupKey] && s.group[groupKey].activeMonitors && s.group[groupKey].activeMonitors[monitorId]){
var monitor = s.group[groupKey].rawMonitorConfigurations[monitorId]
@ -1658,8 +1766,22 @@ module.exports = function(s,config,lang,app,io){
let response = { ok: false };
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_delete.indexOf(req.params.id)===-1){
res.end(user.lang['Not Permitted'])
const monitorId = req.params.id
const groupKey = req.params.ke
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user);
if(
isRestrictedApiKey && apiKeyPermissions.delete_videos_disallowed ||
isRestricted && !monitorPermissions[`${monitorId}_video_delete`]
){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return
}
var time = s.nameToTime(req.params.file)
@ -1675,8 +1797,6 @@ module.exports = function(s,config,lang,app,io){
videoSet = 'Cloud Videos'
break;
}
const groupKey = req.params.ke
const monitorId = req.params.id
s.knexQuery({
action: "select",
columns: "*",

View File

@ -10,6 +10,24 @@ var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({})
var ejs = require('ejs');
module.exports = function(s,config,lang,app){
function cantLiveStreamPermission(user,monitorId,permission){
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
isRestrictedApiKey,
apiKeyPermissions,
} = s.checkPermission(user)
if(
isRestrictedApiKey && apiKeyPermissions[`${permission}_disallowed`] ||
isRestricted && !monitorPermissions[`${monitorId}_monitors`]
){
return true
}
return false
}
var noCache = function(res){
res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate')
res.setHeader('Expires', '-1')
@ -21,6 +39,11 @@ module.exports = function(s,config,lang,app){
app.get([config.webPaths.apiPrefix+':auth/embed/:ke/:id',config.webPaths.apiPrefix+':auth/embed/:ke/:id/:addon'], function (req,res){
req.params.protocol=req.protocol;
s.auth(req.params,function(user){
const monitorId = req.params.id
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
noCache(res)
if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
res.end(user.lang['Not Permitted'])
@ -44,6 +67,11 @@ module.exports = function(s,config,lang,app){
*/
app.get([config.webPaths.apiPrefix+':auth/mp4/:ke/:id/:channel/s.mp4',config.webPaths.apiPrefix+':auth/mp4/:ke/:id/s.mp4',config.webPaths.apiPrefix+':auth/mp4/:ke/:id/:channel/s.ts',config.webPaths.apiPrefix+':auth/mp4/:ke/:id/s.ts'], function (req, res) {
s.auth(req.params,function(user){
const monitorId = req.params.id
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
if(!s.group[req.params.ke] || !s.group[req.params.ke].activeMonitors[req.params.id]){
res.status(404);
res.end('404 : Monitor not found');
@ -108,6 +136,11 @@ module.exports = function(s,config,lang,app){
res.end()
}else{
s.auth(req.params,function(user){
const monitorId = req.params.id
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
s.checkChildProxy(req.params,function(){
if(s.group[req.params.ke]&&s.group[req.params.ke].activeMonitors[req.params.id]){
if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
@ -169,6 +202,11 @@ module.exports = function(s,config,lang,app){
*/
app.get([config.webPaths.apiPrefix+':auth/hls/:ke/:id/:file',config.webPaths.apiPrefix+':auth/hls/:ke/:id/:channel/:file'], function (req,res){
s.auth(req.params,function(user){
const monitorId = req.params.id
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
s.checkChildProxy(req.params,function(){
noCache(res)
if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
@ -195,6 +233,11 @@ module.exports = function(s,config,lang,app){
*/
app.get(config.webPaths.apiPrefix+':auth/jpeg/:ke/:id/s.jpg', function(req,res){
s.auth(req.params,function(user){
const monitorId = req.params.id
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
s.checkChildProxy(req.params,function(){
noCache(res)
if(user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors&&user.details.monitors.indexOf(req.params.id)===-1){
@ -221,9 +264,10 @@ module.exports = function(s,config,lang,app){
*/
app.get(config.webPaths.apiPrefix+':auth/icon/:ke/:id', function(req,res){
s.auth(req.params,async (user) => {
if(user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors&&user.details.monitors.indexOf(req.params.id)===-1){
res.end(user.lang['Not Permitted'])
return
const monitorId = req.params.id
if(cantLiveStreamPermission(user,monitorId,'watch_snapshot')){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
const flags = req.query.noflags ? '' : req.query.flags || '-s 200x200'
res.writeHead(200, {
@ -245,6 +289,10 @@ module.exports = function(s,config,lang,app){
*/
app.get([config.webPaths.apiPrefix+':auth/flv/:ke/:id/s.flv',config.webPaths.apiPrefix+':auth/flv/:ke/:id/:channel/s.flv'], function(req,res) {
s.auth(req.params,function(user){
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
s.checkChildProxy(req.params,function(){
noCache(res)
var Emitter,chunkChannel
@ -302,6 +350,10 @@ module.exports = function(s,config,lang,app){
config.webPaths.apiPrefix+':auth/h264/:ke/:id'
], function (req, res) {
s.auth(req.params,function(user){
if(cantLiveStreamPermission(user,monitorId)){
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
}
s.checkChildProxy(req.params,function(){
noCache(res)
if(!req.query.feed){req.query.feed='1'}

BIN
web/assets/img/splash.avif Normal file

Binary file not shown.

View File

@ -209,13 +209,18 @@ $(document).ready(function(){
permissionsSection.find('.permission-view select').each(function(n,v){
var el = $(v)
var monitorId = el.attr('monitor')
var value = el.val()
var value = el.val() // permissions selected
$.each(value,function(n,permissionNameSelected){
if(!foundSelected[permissionNameSelected])foundSelected[permissionNameSelected] = []
foundSelected[permissionNameSelected].push(monitorId)
})
})
details = Object.assign(details,foundSelected)
details = Object.assign(details,{
'monitors': [],
'monitor_edit': [],
'video_view': [],
'video_delete': [],
},foundSelected)
detailsElement.val(JSON.stringify(details))
}
var getCompleteForm = function(){

View File

@ -59,7 +59,7 @@ $(document).ready(function(){
<div class="d-block pt-4">
<div class="btn-group btn-group-justified">
<a class="btn btn-sm btn-success" download href="${videoUrl}"><i class="fa fa-download"></i> ${lang.Download}</a>
<a class="btn btn-sm btn-danger delete-video"><i class="fa fa-trash-o"></i> ${lang.Delete}</a>
${permissionCheck('video_delete',video.mid) ? `<a class="btn btn-sm btn-danger delete-video"><i class="fa fa-trash-o"></i> ${lang.Delete}</a>` : ''}
</div>
</div>
</div>

View File

@ -158,7 +158,7 @@ $(document).ready(function(e){
<a class="btn btn-sm btn-primary" href="${href}" download title="${lang.Download}"><i class="fa fa-download"></i></a>
<a class="btn btn-sm btn-primary preview-video" href="${href}" title="${lang.Play}"><i class="fa fa-play"></i></a>
<a class="btn btn-sm btn-default open-video" href="${href}" title="${lang.Play}"><i class="fa fa-play"></i></a>
<a class="btn btn-sm btn-danger delete-video" href="${href}" title="${lang.Delete}"><i class="fa fa-trash-o"></i></a>
${permissionCheck('video_delete',file.mid) ? `<a class="btn btn-sm btn-danger delete-video" href="${href}" title="${lang.Delete}"><i class="fa fa-trash-o"></i></a>` : ''}
</div>
`,
}

View File

@ -291,17 +291,17 @@ a {cursor:pointer}
} */
/* Slim Style */
.form-control {
background-color: transparent;
/* background-color: transparent;
border: 1px solid #E3E3E3;
border-radius: 30px;
color: #2c2c2c;
line-height: normal;
font-size: 0.8571em;
box-shadow: none;
box-shadow: none; */
}
.btn-round {
border-width: 1px;
border-radius: 30px !important;
/* border-width: 1px; */
/* border-radius: 30px !important; */
}
.btn, .navbar .navbar-nav>a.btn {
font-weight: 400;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -14,11 +14,11 @@ $(document).ready(function(){
}else{
listElement.append(`
<div class="col-md-12">
<div class="card" package-name="${module.name}">
<div class="card bg-dark" package-name="${module.name}">
<div class="card-body">
<div><h4 class="title mt-0">${humanName}</h4></div>
<div><pre><b>${lang['Time Created']} :</b> ${module.created}</pre></div>
<div><pre><b>${lang['Last Modified']} :</b> ${module.lastModified}</pre></div>
<div class="pb-2"><b>${lang['Time Created']} :</b> ${module.created}</div>
<div class="pb-2"><b>${lang['Last Modified']} :</b> ${module.lastModified}</div>
<div class="mb-2">
${!module.isIgnitor ? `
${module.hasInstaller ? `

View File

@ -1,12 +1,55 @@
$(document).ready(function(){
var changeSuperPreferencesTab = $('#changeSuperPreferences')
var tokenContainer = $('#super-tokens')
var changeSuperPreferencesForm = changeSuperPreferencesTab.find('form')
function generateId(x){
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < x; i++ )
t += p.charAt(Math.floor(Math.random() * p.length));
return t;
}
function drawTokenRow(tokenValue){
var html = `<div class="d-flex flex-row token-row mt-3">
<div class="flex-grow-1">
<input class="form-control form-control-sm token-row-input" value="${tokenValue || generateId(30)}">
</div>
<div>
<a class="delete-token btn btn-danger btn-sm my-0 ml-3"><i class="fa fa-trash"></i></a>
</div>
</div>`
tokenContainer.append(html)
}
function getTokenRows(){
var rowsFound = []
changeSuperPreferencesTab.find('.token-row-input').each(function(n,v){
var el = $(v)
var tokenValue = el.val().trim()
if(tokenValue)rowsFound.push(tokenValue);
})
return rowsFound
}
function loadPreferences(){
var tokens = $user.tokens
changeSuperPreferencesTab.find('[name=mail]').val($user.mail)
if(tokens instanceof Array){
tokens.forEach(function(token){
drawTokenRow(token)
})
}
}
changeSuperPreferencesTab.find('.new-token').click(function(){
drawTokenRow()
})
changeSuperPreferencesTab.on('click','.delete-token',function(){
$(this).parents('.token-row').remove()
})
changeSuperPreferencesTab.find('.submit').click(function(){
changeSuperPreferencesForm.submit()
})
changeSuperPreferencesForm.submit(function(e){
e.preventDefault()
var formValues = $(this).serializeObject()
formValues.tokens = getTokenRows()
// $.ccio.cx({f:'accounts',ff:'saveSuper',form:formValues})
$.post(superApiPrefix + $user.sessionKey + '/accounts/saveSettings',{
data: JSON.stringify(formValues)
@ -15,8 +58,5 @@ $(document).ready(function(){
})
return false
})
function loadPreferences(){
changeSuperPreferencesTab.find('[name=mail]').val($user.mail)
}
loadPreferences()
})

File diff suppressed because one or more lines are too long

View File

@ -37,23 +37,25 @@
<ul id="pageTabLinks" class="nav flex-column nav-pills">
<div class="pb-2 px-3" id="home-collapse">
<% menuInfo.links.forEach((item) => {
if(item.divider){ %>
<li><hr class="dropdown-divider"></li>
<% }else{ %>
<li class="nav-item" <%- item.attributes ? item.attributes : '' %> <%- item.pageOpen ? `id="side-menu-link-${item.pageOpen}"` : '' %>>
<a class="nav-link side-menu-link <%- item.class %>" aria-current="page" <%- item.pageOpen ? `page-open="${item.pageOpen}"` : '' %>>
<i class="fa fa-<%- item.icon %>"></i> &nbsp; <%- item.label %>
</a>
<% if(item.addUl){ %>
<ul class="btn-default rounded btn-toggle-nav list-unstyled fw-normal ml-3 mt-2 px-2 pb-2 pt-1 <%- item.ulClass ? item.ulClass : '' %>">
<% if(item.ulItems){
item.ulItems.forEach((listItem) => { %>
<li><a class="<%- define.Theme.isDark ? 'text-white' : 'text-dark' %> <%- listItem.class ? listItem.class : '' %>" <%- listItem.attributes ? listItem.attributes : '' %>><span class="dot dot-<%- listItem.color ? listItem.color : 'blue' %> shadow mr-2"></span><%- listItem.label ? listItem.label : 'Need Label' %></a></li>
<% })
} %>
</ul>
<% } %>
</li>
if(!item.eval || eval(item.eval)){
if(item.divider){ %>
<li><hr class="dropdown-divider"></li>
<% }else{ %>
<li class="nav-item" <%- item.attributes ? item.attributes : '' %> <%- item.pageOpen ? `id="side-menu-link-${item.pageOpen}"` : '' %>>
<a class="nav-link side-menu-link <%- item.class %>" aria-current="page" <%- item.pageOpen ? `page-open="${item.pageOpen}"` : '' %>>
<i class="fa fa-<%- item.icon %>"></i> &nbsp; <%- item.label %>
</a>
<% if(item.addUl){ %>
<ul class="btn-default rounded btn-toggle-nav list-unstyled fw-normal ml-3 mt-2 px-2 pb-2 pt-1 <%- item.ulClass ? item.ulClass : '' %>">
<% if(item.ulItems){
item.ulItems.forEach((listItem) => { %>
<li><a class="<%- define.Theme.isDark ? 'text-white' : 'text-dark' %> <%- listItem.class ? listItem.class : '' %>" <%- listItem.attributes ? listItem.attributes : '' %>><span class="dot dot-<%- listItem.color ? listItem.color : 'blue' %> shadow mr-2"></span><%- listItem.label ? listItem.label : 'Need Label' %></a></li>
<% })
} %>
</ul>
<% } %>
</li>
<% } %>
<% } %>
<% }) %>
</div>

View File

@ -1,5 +1,5 @@
<% var pageTitle = lang.Shinobi %>
<!-- Header -->
<% include blocks/header.ejs %>
<% include blocks/header-loggedIn.ejs %>
<!-- Page -->

View File

@ -1,3 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Powered by Shinobi, http://shinobi.video -->
<% include blocks/header-title.ejs %>
@ -27,6 +29,7 @@
return string.replace(/'/g,"\\'")
}%>
<% if(screen){screen=screen.toLowerCase()} %>
<body>
<div id="page-contents" class="display-table full-height">
<div class="shinobi-bg-shade bg-gradient-<%- screen === 'super' ? 'green' : 'blue' %>">
<div class="d-flex flex-row full-height">
@ -176,6 +179,7 @@
</div>
</div>
</div>
</body>
<script>
var googleSignIn = false;
<% var failedLogin;if(failedLogin===true){ %>
@ -202,3 +206,4 @@
}
</script>
<% } %>
</html>

View File

@ -78,10 +78,10 @@
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#changeSuperPreferences" role="tab"><%-lang['Preferences']%></a>
</li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#customAutoLoad" role="tab"><%-lang['Custom Auto Load']%></a>
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#easyRemoteAccess" role="tab"><%-lang['Easy Remote Access (P2P)']%></a>
</li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#easyRemoteAccess" role="tab"><%-lang['Easy Remote Access (P2P)']%></a>
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#customAutoLoad" role="tab"><%-lang['Custom Auto Load']%></a>
</li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#superPluginManager" role="tab"><%-lang['Plugin Manager']%></a>