Skip to content

Commit

Permalink
security headers, refresh notif, 404 dir error.
Browse files Browse the repository at this point in the history
  • Loading branch information
0perationPrivacy committed Nov 10, 2021
1 parent b45b0cd commit 64fd697
Show file tree
Hide file tree
Showing 23 changed files with 314 additions and 99 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,19 @@
> Note: Every update deletes the MMS media files/folder
---

## v0.75 (Nov 9, 2021)
### Security
- Protections added as security headers for: XSS, NoSniff, HSTS, X-Powered-By, FrameGuard, DNS Prefetch, Content Security Policy.

### Bugs
- Pull down to refresh now updates the notification dot and the profile inside the dropdown
- Redirect issue to 404 fixed for non-custom directory


## v0.74 (Nov 2, 2021)
- **UI:** Error page CSS fixed
- **UI:** Error page update


## v0.73 (Nov 2, 2021)
### Security
Expand Down
13 changes: 7 additions & 6 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

Please use the app at your own risk. It is in BETA and has not gone through a formal security autdit, scan, code review or assessment.

The focus right now is on functionality and bug fixes and will become mature with time and frequent updates.
The focus right now is on functionality and bug fixes are being addressed as I see them and reported in the issues section.

There is a huge list of tasks we care coding in the backend and everything goes in the pipeline, milestones and roadmap.
There's only so much I can do with the limited time and knowledge I have. So please be kind and patient. (I've already had people point out 50 flaws in 2 days 👏🏼🙄. I'm taking notes and will eventually get there.)
There is a huge list of tasks we are working on in the backend and everything goes in the pipeline, milestones, roadmap and/or issues.
There's only so much I can do with the limited time and knowledge I have. So please be kind and patient. If you want to contribute, please reach out.

Expect security holes, bugs and flaws. Use it at yor own risk.
> Expect security holes, bugs and flaws. Use it at yor own risk.
## Reporting a Vulnerability

When you find a security misconfiguration, vulnerability or anything that can improve security, please report it by either emailing me ([email protected]) or mesaging me using the [Matrix/Element](https://matrix.to/#/#OperationPrivacy:matrix.org) chat.
When you find a security misconfiguration, vulnerability or anything that can improve overall security or privacy, please report it by either emailing me ([email protected]) or mesaging using the [Matrix/Element](https://matrix.to/#/#OperationPrivacy:matrix.org) chat.

**Important:** When reporting a vulnerability, please make sure to suggest a detailed fix as well, it will save me time. (Because I too have a laundry list of fixes that I'm prioritizing). The output of a vulnerability or code scan will be igonored as we already have those and don't add any value to actually finding one.

**Important:** When reporting a vulnerability, please make sure to suggest a detailed fix as well, it will save me time. (Because I too have a laundry list of fixes that I'm prioritizing)
24 changes: 24 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ const cors = require("cors");
require('dotenv').config()
const path = require('path');
var RateLimit = require('express-rate-limit');
const helmet = require("helmet");
app.use(
helmet.contentSecurityPolicy({
useDefaults: true,
reportOnly: false,
directives: {
"default-src": ["'self'", "sdk.twilio.com","wss:","ws:"],
"object-src": ["'self'"],
"script-src": ["'self'","'unsafe-eval'"]
},
})
);
//sdk.twilio.com
app.use(helmet.dnsPrefetchControl());
app.use(helmet.expectCt());
app.use(helmet.frameguard());
app.use(helmet.hidePoweredBy());
app.use(helmet.hsts());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.referrerPolicy());
app.use(helmet.xssFilter());

const server = require('http').createServer(app);

Expand Down Expand Up @@ -44,6 +67,7 @@ io.on('connection', socket => {
});
});

app.use('/frontend/dist/index.html', express.static('frontend/dist/index.html'));
app.use('/version.md', express.static('version.md'));
// app.enable('trust proxy')
if( process.env.HTTPS.trim() === 'true'){
Expand Down
38 changes: 38 additions & 0 deletions app/controller/fallback.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,41 @@ exports.telnyxSipGet = async (req, res) => {
}
};

exports.checkCallSetting = async(req, res) => {
if(req.body.type == 'telnyx') {
var rules = {
api_key: 'required',
number: 'required',
sid: 'required'
};
} else {
var rules = {
twilio_sid: 'required',
twilio_token: 'required',
twilio_number: 'required',
sid: 'required',
}
}
let validation = new Validator(req.body, rules);
if(validation.passes()){
if(req.body.type == 'telnyx'){
var updateData = {
number_sid : req.body.sid,
apiKey: req.body.api_key
}
var numberData = await telnyxHelper.getNumberData(updateData);
res.send({status:'true', message:'Number Data!', data:numberData});
}else{
var updateData = {
sid : req.body.twilio_sid,
token: req.body.twilio_token,
numbersid: req.body.sid
}
var numberData = await twilioHelper.numberGet(updateData);
res.send({status:'true', message:'Number Data!', data:numberData});
}
}else{
res.status(400).send({status: false, message:error.message, data: []});
}
};

108 changes: 62 additions & 46 deletions app/controller/setting.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const { exists } = require('../model/setting.model');
const commonHelper = require('../helper/common.helper')
const telnyxHelper = require('../helper/telnyx.helper')
const twilioHelper = require('../helper/twilio.helper')

exports.deleteKey = async (req, res) => {
var settingCheck = await Setting.findOne({user:req.body.user,_id:req.body.profile_id})
try{
Expand Down Expand Up @@ -141,31 +142,33 @@ exports.create = async (req, res) => {
settingCheck.profile = req.body.profile;
settingCheck.type = 'telnyx';

if(settingCheck.telnyx_twiml){
await telnyxHelper.updateTexmlApp(req.body.api_key, settingCheck.telnyx_twiml)
}else{
var twimlTel = await telnyxHelper.createTexmlApp(req.body.api_key)
settingCheck.telnyx_twiml = twimlTel.data.id
}
if(settingCheck.telnyx_outbound){
// telnyxHelper.updateTexmlApp(req.body.api_key, settingCheck.telnyx_twiml)
}else{
var outboundTel = await telnyxHelper.createOutboundVoice(req.body.api_key)
settingCheck.telnyx_outbound = outboundTel.data.id
}
if (req.body.override === 'true') {
if(settingCheck.telnyx_twiml){
await telnyxHelper.updateTexmlApp(req.body.api_key, settingCheck.telnyx_twiml)
}else{
var twimlTel = await telnyxHelper.createTexmlApp(req.body.api_key)
settingCheck.telnyx_twiml = twimlTel.data.id
}
if(settingCheck.telnyx_outbound){
// telnyxHelper.updateTexmlApp(req.body.api_key, settingCheck.telnyx_twiml)
}else{
var outboundTel = await telnyxHelper.createOutboundVoice(req.body.api_key)
settingCheck.telnyx_outbound = outboundTel.data.id
}

if(settingCheck.sip_id){
await telnyxHelper.updateSIPApp(req.body.api_key, settingCheck.sip_id, settingCheck.telnyx_outbound)
}else{
// console.log('==================================================================')
// console.log(settingCheck.telnyx_outbound)
var sipTel = await telnyxHelper.createSIPApp(req.body.api_key, req.user.id, settingCheck.telnyx_outbound)
//console.log('==================================================================')
// console.log(sipTel.data.id)
settingCheck.sip_id = sipTel.data.id
settingCheck.sip_username = sipTel.data.user_name
settingCheck.sip_password = sipTel.data.password
}
if(settingCheck.sip_id){
await telnyxHelper.updateSIPApp(req.body.api_key, settingCheck.sip_id, settingCheck.telnyx_outbound)
}else{
// console.log('==================================================================')
// console.log(settingCheck.telnyx_outbound)
var sipTel = await telnyxHelper.createSIPApp(req.body.api_key, req.user.id, settingCheck.telnyx_outbound)
//console.log('==================================================================')
// console.log(sipTel.data.id)
settingCheck.sip_id = sipTel.data.id
settingCheck.sip_username = sipTel.data.user_name
settingCheck.sip_password = sipTel.data.password
}
}

settingCheck.save();
var save = settingCheck;
Expand Down Expand Up @@ -208,10 +211,12 @@ exports.create = async (req, res) => {
req.body.sid,
{ messaging_profile_id: telnyxSetting }
);
if (req.body.override === 'true') {
await telnyx(req.body.api_key).phoneNumbers.update(
req.body.sid,
{ connection_id: settingCheck.telnyx_twiml }
);
}
res.send({status:true, message:'setting saved!', data:settingCheck});
}else{
res.status(400).json({status:'false',message:'Setting not saved!'});
Expand Down Expand Up @@ -272,19 +277,20 @@ exports.create = async (req, res) => {
settingCheck.twilio_token = req.body.twilio_token;
settingCheck.profile = req.body.profile;
settingCheck.type = 'twilio';
if (req.body.override === 'true') {
if(settingCheck.twiml_app){
await twilioHelper.updateTwiml(req.body.twilio_sid, req.body.twilio_token, settingCheck.twiml_app)
}else{
var twiml_app = await twilioHelper.creatTwiml(req.body.twilio_sid, req.body.twilio_token);
settingCheck.twiml_app = twiml_app
}
if(settingCheck.app_key){

if(settingCheck.twiml_app){
await twilioHelper.updateTwiml(req.body.twilio_sid, req.body.twilio_token, settingCheck.twiml_app)
}else{
var twiml_app = await twilioHelper.creatTwiml(req.body.twilio_sid, req.body.twilio_token);
settingCheck.twiml_app = twiml_app
}
if(settingCheck.app_key){

}else{
var appData = await twilioHelper.creatAPIKey(req.body.twilio_sid, req.body.twilio_token);
settingCheck.app_key = appData.sid
settingCheck.app_secret = appData.secret
}else{
var appData = await twilioHelper.creatAPIKey(req.body.twilio_sid, req.body.twilio_token);
settingCheck.app_key = appData.sid
settingCheck.app_secret = appData.secret
}
}
var save = settingCheck.save();
}else{
Expand All @@ -300,19 +306,29 @@ exports.create = async (req, res) => {
var save = await Setting.create(twilioData);
}
}
if(save){
const client = new twilio(req.body.twilio_sid, req.body.twilio_token);
client.incomingPhoneNumbers(req.body.sid)
.update({smsUrl: process.env.BASE_URL.trim()+"api/setting/receive-sms/"+req.body.type, voiceUrl: process.env.BASE_URL.trim()+"api/call/incomming", statusCallback: process.env.BASE_URL.trim()+"api/call/status" })
res.send({status:true, message:'setting saved!', data:settingCheck});

}else{
res.status(400).json({status:'false',message:'Setting not saved!'});
}
if(save){
const client = new twilio(req.body.twilio_sid, req.body.twilio_token);
if (req.body.override === 'true') {
var twilioUpdatedata = {
smsUrl: process.env.BASE_URL.trim()+"api/setting/receive-sms/"+req.body.type,
voiceUrl: process.env.BASE_URL.trim()+"api/call/incomming",
statusCallback: process.env.BASE_URL.trim()+"api/call/status",
voiceApplicationSid: "",
}
}else{
var twilioUpdatedata = {
smsUrl: process.env.BASE_URL.trim()+"api/setting/receive-sms/"+req.body.type,
}
}
await client.incomingPhoneNumbers(req.body.sid)
.update(twilioUpdatedata)
res.send({status:true, message:'setting saved!', data:settingCheck});
}else{
res.status(400).json({status:'false',message:'Setting not saved!'});
}
}else{
res.status(400).json({status:'false',message:'Something is wrong!'});
}

}else{
let rules2 = {
profile: 'required'
Expand Down
6 changes: 3 additions & 3 deletions app/controller/user.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ exports.checkDirectoryName = (req, res) => {
var dir = process.env.APPDIRECTORY
if(dir){
if(dir === req.body.dirname){
res.send({status:true, message:'APPDIRECTORY!', data:{status:'true'}});
res.send({status:true, message:'APPDIRECTORY Matched!', data:{status:'true'}});
} else {
res.send({status:true, message:'APPDIRECTORY!', data:{status:'false'}});
res.send({status:true, message:'APPDIRECTORY Mismatch!', data:{status:'false'}});
}
}else{
res.send({status:true, message:'APPDIRECTORY!', data:{status:'nodir'}});
res.send({status:true, message:'APPDIRECTORY not defined!', data:{status:'nodir'}});
}
};
exports.getUpdateVersion = (req, res) => {
Expand Down
21 changes: 19 additions & 2 deletions app/helper/telnyx.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const Telnyx = require('telnyx');
var axios = require('axios');
const moment = require('moment');


//Inside lib file declare functions
const requestCurl = (method,url,headers,data=null) => {
return new Promise((resolve) => {
Expand Down Expand Up @@ -308,6 +307,24 @@ const sIPAppGet = async (data) => {
});
}

const getNumberData = async (data) => {
return new Promise(async (resolve,reject) => {
try{
var url = `https://api.telnyx.com/v2/phone_numbers/${data.number_sid}`;
var headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${data.apiKey}`
};
var response = await requestCurl('GET',url,headers);
resolve(response);
}catch(error){
// console.log(error)
resolve(false);
}
});
}

module.exports = {
requestCurl, createTexmlApp, updateTexmlApp, deleteTexmlApp, createSIPApp, updateSIPApp, deleteSIPApp, createOutboundVoice, deleteOutboundVoice, updatePhoneNumber, emptyMessageProfile, deleteMessageProfile, messageProfileFallback, texmlAppFalback, sIPAppFallback, messageProfileGet, texmlAppGet, sIPAppGet
requestCurl, createTexmlApp, updateTexmlApp, deleteTexmlApp, createSIPApp, updateSIPApp, deleteSIPApp, createOutboundVoice, deleteOutboundVoice, updatePhoneNumber, emptyMessageProfile, deleteMessageProfile, messageProfileFallback, texmlAppFalback, sIPAppFallback, messageProfileGet, texmlAppGet, sIPAppGet, getNumberData
}
2 changes: 2 additions & 0 deletions app/routes/setting.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ module.exports = app => {
router.post("/telnyx/message/get",auth, fallback.telnyxMessageGet);
router.post("/telnyx/twiml/get",auth, fallback.telnyxTwimlGet);
router.post("/telnyx/sip/get",auth, fallback.telnyxSipGet);

router.post("/check-setting",auth, fallback.checkCallSetting);

app.use('/api/setting', router);
};
Loading

0 comments on commit 64fd697

Please sign in to comment.