Skip to content

Commit

Permalink
Merge pull request #196 from moeiscool/dev
Browse files Browse the repository at this point in the history
Docker update and local camera fix
  • Loading branch information
moeiscool authored Jun 16, 2017
2 parents 160bc1b + 5805868 commit 9b522bc
Show file tree
Hide file tree
Showing 19 changed files with 515 additions and 155 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker-entrypoint.sh text eol=lf
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ web.old
.DS_Store
.vagrant
conf.json
super.json
dbdata
30 changes: 22 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
FROM ubuntu:xenial
FROM jrottenberg/ffmpeg:ubuntu
COPY . /opt/shinobi
WORKDIR /opt/shinobi

ENV MYSQL_HOST="shinobi-db" \
ENV MYSQL_HOST="127.0.0.1" \
MYSQL_DATABASE="shinobi" \
MYSQL_ROOT_USER="root" \
MYSQL_ROOT_PASSWORD="rootpass" \
MYSQL_USER="ccio" \
MYSQL_PASSWORD="shinobi"
MYSQL_PASSWORD="shinobi" \
TIMEZONE="UTC"

RUN apt update \
&& apt install --no-install-recommends -y ffmpeg nodejs npm libav-tools \
wget mysql-client \
&& echo mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD | debconf-set-selections \
&& echo mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASSWORD | debconf-set-selections \
&& apt-get install -y mysql-server mysql-client libmysqlclient-dev \
&& apt install -y curl \
&& curl -sL https://deb.nodesource.com/setup_8.x | bash \
&& apt install --no-install-recommends -y nodejs libav-tools \
wget libcairo2-dev libjpeg-dev libpango1.0-dev \
libgif-dev build-essential g++ \
&& apt clean \
&& rm -rf /var/lib/apt/lists/* \
&& ln -s /usr/bin/nodejs /usr/bin/node \
&& cp /opt/shinobi/conf.sample.json /opt/shinobi/conf.json \
&& cp /opt/shinobi/super.sample.json /opt/shinobi/super.json \
&& npm install \
&& npm install pm2 -g \
&& chmod +x ./docker-entrypoint.sh
# && cp /opt/shinobi/plugins/motion/conf.sample.json /opt/shinobi/plugins/motion/conf.json
&& npm install canvas \
&& chmod +x ./docker-entrypoint.sh \
&& cp /opt/shinobi/plugins/motion/conf.sample.json /opt/shinobi/plugins/motion/conf.json \
&& mkdir -p /var/run/mysqld \
&& chown root:root /var/run/mysqld
RUN sed -i -e"s/^user\s*=\s*mysql/user = root/" /etc/mysql/mysql.conf.d/mysqld.cnf \
&& sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/mysql.conf.d/mysqld.cnf

VOLUME ["/opt/shinobi/videos"]
VOLUME ["/var/lib/mysql"]
EXPOSE 8080
EXPOSE 3306
ENTRYPOINT ./docker-entrypoint.sh
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Shinobi is the Open Source CCTV Solution written in Node.JS. Designed with multi

For an updated list of features visit the official website. http://shinobi.video/features

- 2-Factor Authentication
- Defeats stream limit imposed by browsers
- With Base64 (Stream Type) and JPEG Mode (Option)
- Records IP Cameras and Local Cameras
Expand Down Expand Up @@ -47,6 +48,16 @@ After doing so please head on over to the Discord community chat for support. ht

The Issues section is only for bugs with the software. Comments and feature requests may be closed without comment. http://shinobi.video/docs/contribute

Please be considerate of developer efforts. If you have simple questions, like "what does this button do?", please be sure to have read the docs entirely before asking. If you would like to skip reading the docs and ask away you can order a support package :) http://shinobi.video/support

## Making Suggestions or Feature Requests

You can post suggestions in the Discord #suggestions channel. Please do not treat this channel like a "demands" window. Developer efforts are limited. Much more than many alternatives.

when you have a suggestion please try and make the changes yourself then post a pull request to the `dev` branch. Then we can decide if it's a good change for Shinobi. If you don't know how to go about it or would like to skip that and have me do the changes you can order a support package.

http://shinobi.video/support

## Help make Shinobi the best Open Source CCTV Solution.
Donate - http://shinobi.video/docs/donate

Expand Down
141 changes: 107 additions & 34 deletions camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ if(config.pluginKeys===undefined)config.pluginKeys={};


server.listen(config.port,config.bindip);
s={child_help:false,totalmem:os.totalmem(),platform:os.platform(),s:JSON.stringify,isWin:(process.platform==='win32')};
s={factorAuth:{},child_help:false,totalmem:os.totalmem(),platform:os.platform(),s:JSON.stringify,isWin:(process.platform==='win32')};
s.systemLog=function(q,w,e){
if(!w){w=''}
if(!e){e=''}
Expand Down Expand Up @@ -130,6 +130,12 @@ s.gid=function(x){
t += p.charAt(Math.floor(Math.random() * p.length));
return t;
};
s.nid=function(x){
if(!x){x=6};var t = "";var p = "0123456789";
for( var i=0; i < x; i++ )
t += p.charAt(Math.floor(Math.random() * p.length));
return t;
};
s.moment_withOffset=function(e,x){
if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
e=moment(e);if(config.utcOffset){e=e.utcOffset(config.utcOffset)}
Expand Down Expand Up @@ -566,9 +572,14 @@ s.ffmpeg=function(e,x){
//input - analyze duration
if(e.details.aduration&&e.details.aduration!==''){x.cust_input+=' -analyzeduration '+e.details.aduration};
//input - check protocol
switch(e.protocol){
case'rtsp':
if(e.details.rtsp_transport&&e.details.rtsp_transport!==''&&e.details.rtsp_transport!=='no'){x.cust_input+=' -rtsp_transport '+e.details.rtsp_transport;}
//input
switch(e.type){
case'h264':
switch(e.protocol){
case'rtsp':
if(e.details.rtsp_transport&&e.details.rtsp_transport!==''&&e.details.rtsp_transport!=='no'){x.cust_input+=' -rtsp_transport '+e.details.rtsp_transport;}
break;
}
break;
}
//record - resolution
Expand Down Expand Up @@ -2410,11 +2421,43 @@ app.post('/:auth/register/:ke/:uid',function (req,res){
},res,req);
})
//login function
s.deleteFactorAuth=function(r){
delete(s.factorAuth[r.ke][r.uid])
if(Object.keys(s.factorAuth[r.ke]).length===0){
delete(s.factorAuth[r.ke])
}
}
app.post('/',function (req,res){
req.failed=function(){
res.render("index",{failedLogin:true});
res.end();
}
req.fn=function(){
switch(req.body.function){
case'streamer':
sql.query('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"socket"],function(err,rr){
req.resp.mons=rr;
res.render("streamer",{$user:req.resp});
})
break;
case'admin':
if(!r.details.sub){
sql.query('SELECT uid,mail,details FROM Users WHERE ke=? AND details LIKE \'%"sub"%\'',[r.ke],function(err,rr) {
sql.query('SELECT * FROM Monitors WHERE ke=?',[r.ke],function(err,rrr) {
res.render("admin",{$user:req.resp,$subs:rr,$mons:rrr});
})
})
}else{
//not admin user
res.render("home",{$user:req.resp,config:config});
}
break;
default:
res.render("home",{$user:req.resp,config:config});
break;
}
// res.end();
}
if(req.body.mail&&req.body.pass){
if(req.body.function==='super'){
if(!fs.existsSync('./super.json')){
Expand All @@ -2436,30 +2479,40 @@ app.post('/',function (req,res){
sql.query("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[r.auth,r.ke,r.uid])
req.resp={ok:true,auth_token:r.auth,ke:r.ke,uid:r.uid,mail:r.mail,details:r.details};
r.details=JSON.parse(r.details);

req.fn=function(){
switch(req.body.function){
case'streamer':
sql.query('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"socket"],function(err,rr){
req.resp.mons=rr;
res.render("streamer",{$user:req.resp});
})
break;
case'admin':
if(!r.details.sub){
sql.query('SELECT uid,mail,details FROM Users WHERE ke=? AND details LIKE \'%"sub"%\'',[r.ke],function(err,rr) {
sql.query('SELECT * FROM Monitors WHERE ke=?',[r.ke],function(err,rrr) {
res.render("admin",{$user:req.resp,$subs:rr,$mons:rrr});
})
})
}else{
//not admin user
res.render("home",{$user:req.resp,config:config});

req.factorAuth=function(cb){
if(r.details.factorAuth==="1"){
if(!r.details.acceptedMachines||!(r.details.acceptedMachines instanceof Object)){
r.details.acceptedMachines={}
}
if(!r.details.acceptedMachines[req.body.machineID]){
if(!s.factorAuth[r.ke]){s.factorAuth[r.ke]={}}
if(!s.factorAuth[r.ke][r.uid]){
s.factorAuth[r.ke][r.uid]={key:s.nid()}
r.mailOptions = {
from: '"ShinobiCCTV" <[email protected]>',
to: r.mail,
subject: '2-Factor Authentication',
html: 'Enter this code to proceed <b>'+s.factorAuth[r.ke][r.uid].key+'</b>. The code will only be active for 15 minutes. If you login again the timer will be reset to 15 minutes with the same code.',
};
nodemailer.sendMail(r.mailOptions, (error, info) => {
if (error) {
console.log(error)
return ;
}
});
}
break;
default:
res.render("home",{$user:req.resp,config:config});
break;
s.factorAuth[r.ke][r.uid].info=req.resp;
clearTimeout(s.factorAuth[r.ke][r.uid].expireAuth)
s.factorAuth[r.ke][r.uid].expireAuth=setTimeout(function(){
s.deleteFactorAuth(r)
},1000*60*15)
res.render("factor",{$user:req.resp})
}else{
req.fn()
}
}else{
req.fn()
}
}
if(r.details.sub){
Expand All @@ -2468,22 +2521,42 @@ app.post('/',function (req,res){
rr.details=JSON.parse(rr.details);
r.details.mon_groups=rr.details.mon_groups;
req.resp.details=JSON.stringify(r.details);
req.fn();
req.factorAuth()
})
}else{
req.fn()
req.factorAuth()
}




}else{
req.failed()
}
})
}
}else{
req.failed()
if(req.body.machineID&&req.body.factorAuthKey){
if(s.factorAuth[req.body.ke]&&s.factorAuth[req.body.ke][req.body.id]&&s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){
if(s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){
if(req.body.remember==="1"){
req.details=JSON.parse(s.factorAuth[req.body.ke][req.body.id].info.details)
if(!req.details.acceptedMachines||!(req.details.acceptedMachines instanceof Object)){
req.details.acceptedMachines={}
}
if(!req.details.acceptedMachines[req.body.machineID]){
req.details.acceptedMachines[req.body.machineID]={}
sql.query("UPDATE Users SET details=? WHERE ke=? AND uid=?",[s.s(req.details),req.body.ke,req.body.id])
}
}
req.resp=s.factorAuth[req.body.ke][req.body.id].info
req.fn()
}else{
res.render("factor",{$user:s.factorAuth[req.body.ke][req.body.id].info});
res.end();
}
}else{
req.failed()
}
}else{
req.failed()
}
}
});
// Get Motion Buffer stream (m3u8)
Expand Down
21 changes: 8 additions & 13 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@ services:
container_name: shinobi
build:
context: .
depends_on:
- mysql
restart: always
environment:
- MYSQL_HOST=shinobi-db
- MYSQL_HOST=127.0.0.1
- MYSQL_DATABASE=shinobi
- MYSQL_USER=shinobi
- MYSQL_PASSWORD=shinobi_pass
- MYSQL_USER=ccio
- MYSQL_PASSWORD=shinobi
- MYSQL_ROOT_PASSWORD=rootpass
## Timezone - eg Europe/London
- TIMEZONE=UTC
ports:
- "8080:8080"
mysql:
image: mysql:8
container_name: shinobi-db
environment:
- MYSQL_DATABASE=shinobi
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_USER=shinobi
- MYSQL_PASSWORD=shinobi_pass
volumes:
- ./videos:/opt/shinobi/videos
- ./dbdata:/var/lib/mysql
Loading

0 comments on commit 9b522bc

Please sign in to comment.