Merge branch 'fix-sub-account-permissions' into 'dev'

Refactor Sub Account Permissions

See merge request Shinobi-Systems/Shinobi!377
upgrade-sftp-uploader
Moe 2022-08-08 02:12:40 +00:00
commit c3c97ce80b
20 changed files with 901 additions and 433 deletions

View File

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

View File

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

View File

@ -87,11 +87,11 @@ module.exports = function(s,config){
const knexError = (dbQuery,options,err) => { const knexError = (dbQuery,options,err) => {
console.error('knexError----------------------------------- START') console.error('knexError----------------------------------- START')
if(config.debugLogVerbose && config.debugLog === true){ if(config.debugLogVerbose && config.debugLog === true){
s.debugLog('s.knexQuery QUERY',JSON.stringify(options,null,3))
s.debugLog('STACK TRACE, NOT AN ',new Error()) s.debugLog('STACK TRACE, NOT AN ',new Error())
} }
console.error(err) console.error(err)
console.error(dbQuery.toString()) // CANNOT USE `dbQuery.toString()` because it breaks the query
console.error(options)
console.error('knexError----------------------------------- END') console.error('knexError----------------------------------- END')
} }
const knexQuery = (options,callback) => { const knexQuery = (options,callback) => {
@ -149,7 +149,8 @@ module.exports = function(s,config){
} }
} }
if(config.debugLog === true){ 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'){ if(callback || options.update || options.insert || options.action === 'delete'){
dbQuery.asCallback(function(err,r) { 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 groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) const {
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){ monitorPermissions,
s.closeJsonResponse(res,{ monitorRestrictions,
ok: false, } = s.getMonitorsPermitted(user.details,monitorId)
msg: lang['Not Permitted'] 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 return
} }
s.knexQuery({ s.knexQuery({

View File

@ -1773,6 +1773,7 @@ module.exports = function(s,config,lang){
monitorRestrictions.push(['or','mid','=',v]) monitorRestrictions.push(['or','mid','=',v])
} }
}) })
console.log(monitorRestrictions)
}catch(er){ }catch(er){
} }
}else if( }else if(
@ -1790,20 +1791,104 @@ module.exports = function(s,config,lang){
){} ){}
return monitorRestrictions return monitorRestrictions
} }
// s.checkViewerConnectionsForMonitor = function(monitorObject){ s.checkPermission = (user) => {
// var monitorConfig = s.group[monitorObject.ke].rawMonitorConfigurations[monitorObject.mid] // provide "user" object given from "s.auth"
// if(monitorConfig.mode === 'start'){ const isSubAccount = !!user.details.sub
// const response = {
// } isSubAccount,
// } hasAllPermissions: isSubAccount && user.details.allmonitors === '1',
// s.addViewerConnectionForMonitor = function(monitorObject,viewerDetails){ isRestricted: isSubAccount && user.details.allmonitors !== '1',
// s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnection[viewerDetails.viewerId] = viewerDetails isRestrictedApiKey: false,
// s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount += 1 apiKeyPermissions: {},
// return s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount userPermissions: {},
// } }
// s.removeViewerConnectionForMonitor = function(monitorObject,viewerDetails){ const permissions = user.permissions
// delete(s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnection[viewerDetails.viewerId]) const details = user.details;
// s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount -= 1 [
// return s.group[monitorObject.ke].activeMonitors[monitorObject.mid].viewerConnectionCount '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){ app.get(config.webPaths.apiPrefix+':auth/onvifDeviceManager/:ke/:id',function (req,res){
s.auth(req.params,async (user) => { 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} const endData = {ok: true}
try{ try{
const groupKey = req.params.ke
const monitorId = req.params.id
const onvifDevice = await getOnvifDevice(groupKey,monitorId) const onvifDevice = await getOnvifDevice(groupKey,monitorId)
const cameraInfo = await getUIFieldValues(onvifDevice) const cameraInfo = await getUIFieldValues(onvifDevice)
endData.onvifData = cameraInfo 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){ app.post(config.webPaths.apiPrefix+':auth/onvifDeviceManager/:ke/:id/save',function (req,res){
s.auth(req.params,async (user) => { 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 endData = {ok: true}
const responses = {} const responses = {}
try{ try{
const groupKey = req.params.ke
const monitorId = req.params.id
const onvifDevice = await getOnvifDevice(groupKey,monitorId) const onvifDevice = await getOnvifDevice(groupKey,monitorId)
const form = s.getPostData(req) const form = s.getPostData(req)
const videoToken = form.VideoConfiguration && form.VideoConfiguration.videoToken ? form.VideoConfiguration.videoToken : null 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){ app.get(config.webPaths.apiPrefix+':auth/onvifDeviceManager/:ke/:id/reboot',function (req,res){
s.auth(req.params,async (user) => { 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 endData = {ok: true}
try{ try{
const groupKey = req.params.ke
const monitorId = req.params.id
const onvifDevice = await getOnvifDevice(groupKey,monitorId) const onvifDevice = await getOnvifDevice(groupKey,monitorId)
const cameraInfo = await rebootCamera(onvifDevice) const cameraInfo = await rebootCamera(onvifDevice)
endData.onvifData = cameraInfo 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){ app.get(config.webPaths.apiPrefix+':auth/probe/:ke',function (req,res){
s.auth(req.params,function(user){ 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) => { ffprobe(req.query.url,req.params.auth,(endData) => {
s.closeJsonResponse(res,endData) s.closeJsonResponse(res,endData)
}) })

View File

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

View File

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

View File

@ -16,9 +16,11 @@ module.exports = function(s,config,lang,app){
var endData = { var endData = {
ok : false ok : false
} }
if(user.details.sub){ const {
endData.msg = user.lang['Not Permitted'] isSubAccount,
s.closeJsonResponse(res,endData) } = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return return
} }
var form = s.getPostData(req) var form = s.getPostData(req)
@ -103,9 +105,11 @@ module.exports = function(s,config,lang,app){
var endData = { var endData = {
ok : false ok : false
} }
if(user.details.sub){ const {
endData.msg = user.lang['Not Permitted'] isSubAccount,
s.closeJsonResponse(res,endData) } = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return return
} }
var form = s.getPostData(req) || {} var form = s.getPostData(req) || {}
@ -174,9 +178,11 @@ module.exports = function(s,config,lang,app){
var endData = { var endData = {
ok : false ok : false
} }
if(user.details.sub){ const {
endData.msg = user.lang['Not Permitted'] isSubAccount,
s.closeJsonResponse(res,endData) } = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return return
}else{ }else{
endData.ok = true endData.ok = true
@ -209,9 +215,11 @@ module.exports = function(s,config,lang,app){
} }
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ s.auth(req.params,function(user){
if(user.details.sub){ const {
endData.msg = user.lang['Not an Administrator Account'] isSubAccount,
s.closeJsonResponse(res,endData) } = s.checkPermission(user)
if(isSubAccount){
s.closeJsonResponse(res,{ok: false, msg: lang['Not an Administrator Account']});
return return
} }
var form = s.getPostData(req) var form = s.getPostData(req)
@ -290,7 +298,26 @@ module.exports = function(s,config,lang,app){
} }
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ 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'){ if(req.params.f !== 'delete'){
var form = s.getPostData(req) var form = s.getPostData(req)
if(!form){ if(!form){
@ -299,66 +326,46 @@ module.exports = function(s,config,lang,app){
return return
} }
form.mid = req.params.id.replace(/[^\w\s]/gi,'').replace(/ /g,'') form.mid = req.params.id.replace(/[^\w\s]/gi,'').replace(/ /g,'')
if(!user.details.sub || if(form && form.name){
user.details.allmonitors === '1' || s.checkDetails(form)
hasRestrictions && user.details.monitor_edit.indexOf(form.mid) >- 1 || form.ke = req.params.ke
hasRestrictions && user.details.monitor_create === '1'){ s.addOrEditMonitor(form,function(err,endData){
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']
res.end(s.prettyPrint(endData)) res.end(s.prettyPrint(endData))
},user)
}else{
endData.msg = user.lang.monitorEditText1;
res.end(s.prettyPrint(endData))
} }
}else{ }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, ke: req.params.ke,
mid: req.params.id mid: req.params.id,
},{ }
type: 'Monitor Deleted', })
msg: 'by user : '+user.uid if(req.query.deleteFiles === 'true'){
}); deleteMonitorData(req.params.ke,req.params.id).then(() => {
req.params.delete=1;s.camera('stop',req.params); s.debugLog(`Deleted Monitor Data`,{
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, ke: req.params.ke,
mid: req.params.id, 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) },res,req)
}) })
@ -509,9 +516,18 @@ module.exports = function(s,config,lang,app){
var endData = { var endData = {
ok : false ok : false
} }
if(user.details.sub){ const groupKey = req.params.ke
endData.msg = user.lang['Not Permitted'] const {
s.closeJsonResponse(res,endData) 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 return
} }
s.knexQuery({ s.knexQuery({
@ -547,9 +563,18 @@ module.exports = function(s,config,lang,app){
var endData = { var endData = {
ok : false ok : false
} }
if(user.details.sub){ const groupKey = req.params.ke
endData.msg = user.lang['Not Permitted'] const {
s.closeJsonResponse(res,endData) 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 return
} }
var presetQueryVals = [req.params.ke,'monitorStates',req.params.stateName] 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){ s.auth(req.params,function(user){
const groupKey = req.params.ke const groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) const {
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){ 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,[]); s.closeJsonResponse(res,[]);
return return
} }
@ -752,8 +766,22 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,(user) => { s.auth(req.params,(user) => {
const groupKey = req.params.ke const groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) const {
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.get_monitors === "0" || monitorRestrictions.length === 0)){ 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,[]); s.closeJsonResponse(res,[]);
return return
} }
@ -831,11 +859,19 @@ module.exports = function(s,config,lang,app,io){
s.auth(req.params,async (user) => { s.auth(req.params,async (user) => {
const groupKey = req.params.ke const groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const {
monitorPermissions,
monitorRestrictions,
} = s.getMonitorsPermitted(user.details,monitorId)
const {
isRestricted,
userPermissions,
apiKeyPermissions,
isRestrictedApiKey,
} = s.checkPermission(user)
if( if(
user.permissions.control_monitors === "0" || isRestrictedApiKey && apiKeyPermissions.control_monitors_disallowed ||
user.details.sub && isRestricted && !monitorPermissions[`${monitorId}_monitor_edit`]
user.details.allmonitors !== '1' &&
user.details.monitor_edit.indexOf(monitorId) === -1
){ ){
response.msg = user.lang['Not Permitted'] response.msg = user.lang['Not Permitted']
}else{ }else{
@ -860,64 +896,64 @@ module.exports = function(s,config,lang,app,io){
s.closeJsonResponse(res,response); s.closeJsonResponse(res,response);
},res,req); },res,req);
}); });
/** // /**
* API : Merge Recorded Videos into one file // * API : Merge Recorded Videos into one file
*/ // */
app.get(config.webPaths.apiPrefix+':auth/videosMerge/:ke', function (req,res){ // app.get(config.webPaths.apiPrefix+':auth/videosMerge/:ke', function (req,res){
var failed = function(resp){ // var failed = function(resp){
res.setHeader('Content-Type', 'application/json'); // res.setHeader('Content-Type', 'application/json');
res.end(s.prettyPrint(resp)) // res.end(s.prettyPrint(resp))
} // }
if(req.query.videos && req.query.videos !== ''){ // if(req.query.videos && req.query.videos !== ''){
s.auth(req.params,function(user){ // s.auth(req.params,function(user){
var videosSelected = JSON.parse(req.query.videos) // var videosSelected = JSON.parse(req.query.videos)
const whereQuery = [] // const whereQuery = []
var didOne = false // var didOne = false
videosSelected.forEach(function(video){ // videosSelected.forEach(function(video){
var time = s.nameToTime(video.filename) // var time = s.nameToTime(video.filename)
if(req.query.isUTC === 'true'){ // if(req.query.isUTC === 'true'){
time = s.utcToLocal(time) // time = s.utcToLocal(time)
} // }
if(didOne){ // if(didOne){
whereQuery.push(['or','ke','=',req.params.ke]) // whereQuery.push(['or','ke','=',req.params.ke])
}else{ // }else{
didOne = true // didOne = true
whereQuery.push(['ke','=',req.params.ke]) // whereQuery.push(['ke','=',req.params.ke])
} // }
whereQuery.push( // whereQuery.push(
['mid','=',video.mid], // ['mid','=',video.mid],
['time','=',time], // ['time','=',time],
) // )
//
}) // })
s.knexQuery({ // s.knexQuery({
action: "select", // action: "select",
columns: "*", // columns: "*",
table: "Videos", // table: "Videos",
where: whereQuery // where: whereQuery
},(err,r) => { // },(err,r) => {
var resp = {ok: false} // var resp = {ok: false}
if(r && r[0]){ // if(r && r[0]){
s.mergeRecordedVideos(r,req.params.ke,function(fullPath,filename){ // s.mergeRecordedVideos(r,req.params.ke,function(fullPath,filename){
res.setHeader('Content-Disposition', 'attachment; filename="'+filename+'"') // res.setHeader('Content-Disposition', 'attachment; filename="'+filename+'"')
var file = fs.createReadStream(fullPath) // var file = fs.createReadStream(fullPath)
file.on('close',function(){ // file.on('close',function(){
setTimeout(function(){ // setTimeout(function(){
s.file('delete',fullPath) // s.file('delete',fullPath)
},1000 * 60 * 3) // },1000 * 60 * 3)
res.end() // res.end()
}) // })
file.pipe(res) // file.pipe(res)
}) // })
}else{ // }else{
failed({ok:false,msg:'No Videos Found'}) // failed({ok:false,msg:'No Videos Found'})
} // }
}) // })
},res,req); // },res,req);
}else{ // }else{
failed({ok:false,msg:'"videos" query variable is missing from request.'}) // failed({ok:false,msg:'"videos" query variable is missing from request.'})
} // }
}) // })
/** /**
* API : Get Videos * API : Get Videos
*/ */
@ -929,10 +965,27 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){ ], function (req,res){
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id const monitorId = req.params.id
const groupKey = req.params.ke 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 origURL = req.originalUrl.split('/')
var videoParam = origURL[origURL.indexOf(req.params.auth) + 1] var videoParam = origURL[origURL.indexOf(req.params.auth) + 1]
var videoSet = 'Videos' var videoSet = 'Videos'
@ -957,11 +1010,7 @@ module.exports = function(s,config,lang,app,io){
endIsStartTo: !!req.query.endIsStartTo, endIsStartTo: !!req.query.endIsStartTo,
parseRowDetails: false, parseRowDetails: false,
rowName: 'videos', rowName: 'videos',
preliminaryValidationFailed: ( preliminaryValidationFailed: false
user.permissions.watch_videos === "0" ||
hasRestrictions &&
(!userDetails.video_view || userDetails.video_view.indexOf(monitorId)===-1)
)
},(response) => { },(response) => {
if(response && response.videos){ if(response && response.videos){
s.buildVideoLinks(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 searchQuery = s.getPostData(req,'search')
const startTime = s.getPostData(req,'start') const startTime = s.getPostData(req,'start')
const endTime = s.getPostData(req,'end') const endTime = s.getPostData(req,'end')
const userDetails = user.details
const monitorId = req.params.id const monitorId = req.params.id
const groupKey = req.params.ke 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({ getVideosBasedOnTagFoundInMatrixOfAssociatedEvent({
groupKey, groupKey,
monitorId, monitorId,
@ -1020,17 +1086,28 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){ ], function (req,res){
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id const monitorId = req.params.id
const groupKey = req.params.ke const groupKey = req.params.ke
const hasRestrictions = userDetails.sub && userDetails.allmonitors !== '1'; const {
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) monitorPermissions,
const preliminaryValidationFailed = ( monitorRestrictions,
user.permissions.watch_videos === "0" || } = s.getMonitorsPermitted(user.details,monitorId)
hasRestrictions && const {
(!userDetails.video_view || userDetails.video_view.indexOf(monitorId)===-1) isRestricted,
); isRestrictedApiKey,
if(req.query.onlyCount === '1' && !preliminaryValidationFailed){ 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} const response = {ok: true}
s.knexQuery({ s.knexQuery({
action: "count", action: "count",
@ -1068,7 +1145,7 @@ module.exports = function(s,config,lang,app,io){
noFormat: true, noFormat: true,
noCount: true, noCount: true,
rowName: 'events', rowName: 'events',
preliminaryValidationFailed: preliminaryValidationFailed preliminaryValidationFailed: false
},(response) => { },(response) => {
res.end(s.prettyPrint(response)) res.end(s.prettyPrint(response))
}) })
@ -1084,10 +1161,21 @@ module.exports = function(s,config,lang,app,io){
], function (req,res){ ], function (req,res){
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id
const groupKey = req.params.ke 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({ s.sqlQueryBetweenTimesWithPermissions({
table: 'Logs', table: 'Logs',
user: user, user: user,
@ -1102,9 +1190,7 @@ module.exports = function(s,config,lang,app,io){
noFormat: true, noFormat: true,
noCount: true, noCount: true,
rowName: 'logs', rowName: 'logs',
preliminaryValidationFailed: ( preliminaryValidationFailed: false
user.permissions.get_logs === "0" || userDetails.sub && userDetails.view_logs !== '1'
)
},(response) => { },(response) => {
response.forEach(function(v,n){ response.forEach(function(v,n){
v.info = JSON.parse(v.info) v.info = JSON.parse(v.info)
@ -1114,51 +1200,30 @@ module.exports = function(s,config,lang,app,io){
},res,req) },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 * 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){ 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}; var response = {ok:false};
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ 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){ const groupKey = req.params.ke
res.end(user.lang['Not Permitted']) 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 return
} }
if(req.params.f===''){response.msg = user.lang.monitorGetText1;res.end(s.prettyPrint(response));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){ s.auth(req.params,function(user){
const groupKey = req.params.ke const groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) const {
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.watch_videos === "0" || monitorRestrictions.length === 0)){ monitorPermissions,
s.closeJsonResponse(res,{ monitorRestrictions,
ok: false, } = s.getMonitorsPermitted(user.details,monitorId)
msg: lang['Not Permitted'] 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 return
} }
var time = s.nameToTime(req.params.file) 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){ s.auth(req.params,function(user){
const groupKey = req.params.ke const groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) const {
if(user.details.sub && user.details.allmonitors === '0' && (user.permissions.watch_videos === "0" || monitorRestrictions.length === 0)){ monitorPermissions,
s.closeJsonResponse(res,{ monitorRestrictions,
ok: false, } = s.getMonitorsPermitted(user.details,monitorId)
msg: lang['Not Permitted'] 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 return
} }
var time = s.nameToTime(req.params.file) 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){ app.get(config.webPaths.apiPrefix+':auth/motion/:ke/:id', function (req,res){
s.auth(req.params,function(user){ s.auth(req.params,function(user){
const groupKey = req.params.ke const groupKey = req.params.ke
const monitorId = req.params.id const monitorId = req.params.id
const monitorRestrictions = s.getMonitorRestrictions(user.details,monitorId) const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId]
const {
if(user.details.sub && user.details.allmonitors === '0' && monitorRestrictions.length === 0){ monitorPermissions,
s.closeJsonResponse(res,{ monitorRestrictions,
ok: false, } = s.getMonitorsPermitted(user.details,monitorId);
msg: lang['Not Permitted'] const {
}) isRestricted,
return isRestrictedApiKey,
} apiKeyPermissions,
} = s.checkPermission(user);
const d = { 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, id: req.params.id,
ke: req.params.ke ke: req.params.ke
} }
if(req.query.data){ if(req.query.data){
try{ try{
Object.assign(d, {details: s.parseJSON(req.query.data)}); Object.assign(simulatedEvent, {details: s.parseJSON(req.query.data)});
}catch(err){ }catch(err){
s.closeJsonResponse(res,{ s.closeJsonResponse(res,{
ok: false, 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) // 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) { else if(req.query.plug && req.query.name && req.query.reason && req.query.confidence) {
Object.assign(d, { const {
plug,
reason,
confidence,
name,
} = req.query;
Object.assign(simulatedEvent,{
details: { details: {
plug: req.query.plug, plug,
reason: req.query.reason, reason,
confidence: req.query.confidence, confidence,
name: req.query.name name,
} }
}); });
} }
@ -1445,51 +1541,21 @@ module.exports = function(s,config,lang,app,io){
}) })
return 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 details = s.group[d.ke].rawMonitorConfigurations[d.id].details
var detectorHttpApi = details.detector_http_api var detectorHttpApi = details.detector_http_api
var detectorOn = (details.detector === '1') var detectorOn = (details.detector === '1')
switch(detectorHttpApi){ if(
case'0': detectorHttpApi === '0' ||
s.closeJsonResponse(res,{ detectorHttpApi === '2' && !detectorOn ||
ok: false, detectorHttpApi === '3' && detectorOn
msg: user.lang['Trigger Blocked'] ){
}) s.closeJsonResponse(res,{
return ok: false,
break; msg: user.lang['Trigger Blocked']
case'2': })
if(!detectorOn){ return;
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;
} }
triggerEvent(d) triggerEvent(simulatedEvent)
s.closeJsonResponse(res,{ s.closeJsonResponse(res,{
ok: true, ok: true,
msg: user.lang['Trigger Successful'] 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){ app.get(config.webPaths.apiPrefix+':auth/eventCountStatus/:ke/:id', function (req,res){
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ 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){ const monitorId = req.params.id
res.end(user.lang['Not Permitted']) 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 return
} }
var selectedObject = s.group[req.params.ke].activeMonitors[req.params.id].eventsCounted 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){ ], function (req,res){
res.setHeader('Content-Type', 'application/json') res.setHeader('Content-Type', 'application/json')
s.auth(req.params,function(user){ s.auth(req.params,function(user){
const userDetails = user.details
const monitorId = req.params.id const monitorId = req.params.id
const groupKey = req.params.ke 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({ s.sqlQueryBetweenTimesWithPermissions({
table: 'Events Counts', table: 'Events Counts',
user: user, user: user,
@ -1552,11 +1652,7 @@ module.exports = function(s,config,lang,app,io){
endIsStartTo: !!req.query.endIsStartTo, endIsStartTo: !!req.query.endIsStartTo,
parseRowDetails: true, parseRowDetails: true,
rowName: 'counts', rowName: 'counts',
preliminaryValidationFailed: ( preliminaryValidationFailed: false
user.permissions.watch_videos === "0" ||
hasRestrictions &&
(!userDetails.video_view || userDetails.video_view.indexOf(monitorId)===-1)
)
},(response) => { },(response) => {
res.end(s.prettyPrint(response)) res.end(s.prettyPrint(response))
}) })
@ -1597,12 +1693,24 @@ module.exports = function(s,config,lang,app,io){
var response = {ok:false} var response = {ok:false}
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ 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){ const groupKey = req.params.ke
res.end(user.lang['Not Permitted']) 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 return
} }
var groupKey = req.params.ke
var monitorId = req.params.id
// req.query.overwrite === '1' // req.query.overwrite === '1'
if(s.group[groupKey] && s.group[groupKey].activeMonitors && s.group[groupKey].activeMonitors[monitorId]){ if(s.group[groupKey] && s.group[groupKey].activeMonitors && s.group[groupKey].activeMonitors[monitorId]){
var monitor = s.group[groupKey].rawMonitorConfigurations[monitorId] var monitor = s.group[groupKey].rawMonitorConfigurations[monitorId]
@ -1658,8 +1766,22 @@ module.exports = function(s,config,lang,app,io){
let response = { ok: false }; let response = { ok: false };
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){ 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){ const monitorId = req.params.id
res.end(user.lang['Not Permitted']) 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 return
} }
var time = s.nameToTime(req.params.file) var time = s.nameToTime(req.params.file)
@ -1675,8 +1797,6 @@ module.exports = function(s,config,lang,app,io){
videoSet = 'Cloud Videos' videoSet = 'Cloud Videos'
break; break;
} }
const groupKey = req.params.ke
const monitorId = req.params.id
s.knexQuery({ s.knexQuery({
action: "select", action: "select",
columns: "*", columns: "*",

View File

@ -10,6 +10,24 @@ var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({}) var proxy = httpProxy.createProxyServer({})
var ejs = require('ejs'); var ejs = require('ejs');
module.exports = function(s,config,lang,app){ 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){ var noCache = function(res){
res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate') res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate')
res.setHeader('Expires', '-1') 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){ 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; req.params.protocol=req.protocol;
s.auth(req.params,function(user){ 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) noCache(res)
if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ 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']) 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) { 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){ 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]){ if(!s.group[req.params.ke] || !s.group[req.params.ke].activeMonitors[req.params.id]){
res.status(404); res.status(404);
res.end('404 : Monitor not found'); res.end('404 : Monitor not found');
@ -108,6 +136,11 @@ module.exports = function(s,config,lang,app){
res.end() res.end()
}else{ }else{
s.auth(req.params,function(user){ 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(){ s.checkChildProxy(req.params,function(){
if(s.group[req.params.ke]&&s.group[req.params.ke].activeMonitors[req.params.id]){ 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){ 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){ 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){ 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(){ s.checkChildProxy(req.params,function(){
noCache(res) noCache(res)
if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ 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){ app.get(config.webPaths.apiPrefix+':auth/jpeg/:ke/:id/s.jpg', function(req,res){
s.auth(req.params,function(user){ 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(){ s.checkChildProxy(req.params,function(){
noCache(res) noCache(res)
if(user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors&&user.details.monitors.indexOf(req.params.id)===-1){ 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){ app.get(config.webPaths.apiPrefix+':auth/icon/:ke/:id', function(req,res){
s.auth(req.params,async (user) => { 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){ const monitorId = req.params.id
res.end(user.lang['Not Permitted']) if(cantLiveStreamPermission(user,monitorId,'watch_snapshot')){
return s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
return;
} }
const flags = req.query.noflags ? '' : req.query.flags || '-s 200x200' const flags = req.query.noflags ? '' : req.query.flags || '-s 200x200'
res.writeHead(200, { 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) { 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){ 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(){ s.checkChildProxy(req.params,function(){
noCache(res) noCache(res)
var Emitter,chunkChannel var Emitter,chunkChannel
@ -302,6 +350,10 @@ module.exports = function(s,config,lang,app){
config.webPaths.apiPrefix+':auth/h264/:ke/:id' config.webPaths.apiPrefix+':auth/h264/:ke/:id'
], function (req, res) { ], function (req, res) {
s.auth(req.params,function(user){ 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(){ s.checkChildProxy(req.params,function(){
noCache(res) noCache(res)
if(!req.query.feed){req.query.feed='1'} if(!req.query.feed){req.query.feed='1'}

View File

@ -209,13 +209,18 @@ $(document).ready(function(){
permissionsSection.find('.permission-view select').each(function(n,v){ permissionsSection.find('.permission-view select').each(function(n,v){
var el = $(v) var el = $(v)
var monitorId = el.attr('monitor') var monitorId = el.attr('monitor')
var value = el.val() var value = el.val() // permissions selected
$.each(value,function(n,permissionNameSelected){ $.each(value,function(n,permissionNameSelected){
if(!foundSelected[permissionNameSelected])foundSelected[permissionNameSelected] = [] if(!foundSelected[permissionNameSelected])foundSelected[permissionNameSelected] = []
foundSelected[permissionNameSelected].push(monitorId) 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)) detailsElement.val(JSON.stringify(details))
} }
var getCompleteForm = function(){ var getCompleteForm = function(){

View File

@ -59,7 +59,7 @@ $(document).ready(function(){
<div class="d-block pt-4"> <div class="d-block pt-4">
<div class="btn-group btn-group-justified"> <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-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> </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" 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-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-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> </div>
`, `,
} }

View File

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

View File

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

View File

@ -1,12 +1,55 @@
$(document).ready(function(){ $(document).ready(function(){
var changeSuperPreferencesTab = $('#changeSuperPreferences') var changeSuperPreferencesTab = $('#changeSuperPreferences')
var tokenContainer = $('#super-tokens')
var changeSuperPreferencesForm = changeSuperPreferencesTab.find('form') 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(){ changeSuperPreferencesTab.find('.submit').click(function(){
changeSuperPreferencesForm.submit() changeSuperPreferencesForm.submit()
}) })
changeSuperPreferencesForm.submit(function(e){ changeSuperPreferencesForm.submit(function(e){
e.preventDefault() e.preventDefault()
var formValues = $(this).serializeObject() var formValues = $(this).serializeObject()
formValues.tokens = getTokenRows()
// $.ccio.cx({f:'accounts',ff:'saveSuper',form:formValues}) // $.ccio.cx({f:'accounts',ff:'saveSuper',form:formValues})
$.post(superApiPrefix + $user.sessionKey + '/accounts/saveSettings',{ $.post(superApiPrefix + $user.sessionKey + '/accounts/saveSettings',{
data: JSON.stringify(formValues) data: JSON.stringify(formValues)
@ -15,8 +58,5 @@ $(document).ready(function(){
}) })
return false return false
}) })
function loadPreferences(){
changeSuperPreferencesTab.find('[name=mail]').val($user.mail)
}
loadPreferences() loadPreferences()
}) })

View File

@ -37,23 +37,25 @@
<ul id="pageTabLinks" class="nav flex-column nav-pills"> <ul id="pageTabLinks" class="nav flex-column nav-pills">
<div class="pb-2 px-3" id="home-collapse"> <div class="pb-2 px-3" id="home-collapse">
<% menuInfo.links.forEach((item) => { <% menuInfo.links.forEach((item) => {
if(item.divider){ %> if(!item.eval || eval(item.eval)){
<li><hr class="dropdown-divider"></li> if(item.divider){ %>
<% }else{ %> <li><hr class="dropdown-divider"></li>
<li class="nav-item" <%- item.attributes ? item.attributes : '' %> <%- item.pageOpen ? `id="side-menu-link-${item.pageOpen}"` : '' %>> <% }else{ %>
<a class="nav-link side-menu-link <%- item.class %>" aria-current="page" <%- item.pageOpen ? `page-open="${item.pageOpen}"` : '' %>> <li class="nav-item" <%- item.attributes ? item.attributes : '' %> <%- item.pageOpen ? `id="side-menu-link-${item.pageOpen}"` : '' %>>
<i class="fa fa-<%- item.icon %>"></i> &nbsp; <%- item.label %> <a class="nav-link side-menu-link <%- item.class %>" aria-current="page" <%- item.pageOpen ? `page-open="${item.pageOpen}"` : '' %>>
</a> <i class="fa fa-<%- item.icon %>"></i> &nbsp; <%- item.label %>
<% if(item.addUl){ %> </a>
<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.addUl){ %>
<% if(item.ulItems){ <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 : '' %>">
item.ulItems.forEach((listItem) => { %> <% if(item.ulItems){
<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> 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> } %>
<% } %> </ul>
</li> <% } %>
</li>
<% } %>
<% } %> <% } %>
<% }) %> <% }) %>
</div> </div>

View File

@ -78,10 +78,10 @@
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#changeSuperPreferences" role="tab"><%-lang['Preferences']%></a> <a class="nav-link" data-bs-toggle="tab" data-bs-target="#changeSuperPreferences" role="tab"><%-lang['Preferences']%></a>
</li> </li>
<li class="nav-item"> <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>
<li class="nav-item"> <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>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#superPluginManager" role="tab"><%-lang['Plugin Manager']%></a> <a class="nav-link" data-bs-toggle="tab" data-bs-target="#superPluginManager" role="tab"><%-lang['Plugin Manager']%></a>