shhwallet
Version:
305 lines (244 loc) • 11.5 kB
JavaScript
/*
* main.js
* Package: shhwallet
*
* Description : Authorization Server..
* Author: Arun Panneerselvam
* email: arun@gsunitedtechnologies.com
* website: aeroarunn.com
*/
;
const config = require( "./config.js" );
var http = require('http');
var https = require('https');
var fs = require('fs');
var md5 = require('md5');
var util = require('util');
var Promise = require('promise');
var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var https = require('https');
var cors = require('cors');
var apiRoutes = require('./routes.js');
var btcRoutes = require('./btcping.js'); //Ping external servers
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var User = require('../model/user.js'); // get our mongoose model
var ReqLog = require('../model/requests.js'); //get req logger model
/* --------------------------------------------------
* Configuration
*
* --------------------------------------------------
*/
/*
* SSL Server Params
*/
var options = {
key: fs.readFileSync('/home/shhnetworks/ssl.key'),
cert: fs.readFileSync('/home/shhnetworks/ssl.cert'),
};
var corsOptions = {
origin: config.site.origin,
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
var app = express(); //express app
//var port = process.env.PORT || 3030;
var https_port = process.env.PORT || 3030;
// Set API Secret
app.set('superSecret', config.api['secret']);
/* --------------------------------------------------
* connect to Mongo
*
* --------------------------------------------------
*/
try {
global.db = mongoose.connect(config.api.database); //- connect db in classic way
}catch(err) {
global.db = mongoose.createConnection(config.api.database); //- connect in modern mongo way
}
/* --------------------------------------------------
* Create the https server
*
* --------------------------------------------------
*/
https.createServer(options, app).listen(https_port, function(){
//if(err) console.log(err.toString());
console.log("HTTPS server listening on port " + https_port);
});
// use body parser to get info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// console logging using morgan
app.use(morgan('dev'));
//Use of cors for https origin issues
app.use(cors());
/* --------------------------------------------------
* Basic Route
*
* --------------------------------------------------
*/
app.get('/', function(req, res) {
res.send('SHH Authorization HTTPS server at https://shhnetworks.com:' + https_port + '/api');
});
/* --------------------------------------------------
* Default user setup
*
* --------------------------------------------------
*/
app.get('/setup', cors(corsOptions), function(req, res) {
// create a sample user
var admin = new User({
name: 'aeroarunn',
pass: 'sgpajsep2',
token: '17rbCMnaDixPxmp',
secret: '9mu2L4VeiWkPLXEoWAbvwzb-shhserver',
updated: Date.now(),
status: true,
admin: true
});
// save the sample user
admin.save(function(err) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
/* --------------------------------------------------
* Request authorization through both GET & POST
*
* --------------------------------------------------
*/
app.get('/auth', cors(corsOptions), function (req, res) { console.log('Method: GET'); //through GET
// IP Address of request
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
var auth_secret = req.query.client_secret || req.query.auth_secret ;
_authorize('/auth', req, res, ip, auth_secret);
});
app.post('/auth', cors(corsOptions), function(req, res) { console.log('Method: POST'); //through POST
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
var auth_secret = req.body.client_secret || req.body.auth_secret ;
_authorize('/auth', req, res, ip, auth_secret);
});
// Function to call
function _authorize(uri, req, res, ip, auth_secret) { //trough POST
var id = req.body.client_id || req.query.client_id ;
var code = req.body.code || req.query.code ;
var ruri = req.query['redirect_uri'] || req.body['redirect_uri'];
var auth_type = req.query['grant_type'] || req.body['grant_type'];
var response_type = req.query['response_type'] || req.body['response_type'];
var token_type = req.query['token_type'] || req.body['token_type'];
var access_token = req.query['access_token'] || req.body['access_token'];
//console.log(ip);
//Log the request
var auth_log = new ReqLog({ u_id : req.query.client_id, when : Date.now(), from : ip, });
auth_log.save(function(err) { if (err) throw err; console.log('Request logged successfully'); }); //res.json({ success: true });
User.findOne({ // find the user
_id: id, //secret: req.query.secret, //redirect_uri: req.body.redirect_uri,
}, function(err, user) {
if (err) console.log(err);
if (!user) {
res.format({
'text/plain': function () {
res.send({success: false, message: 'Access denied, No such user!'});
},
});
} else if (user) {
// check if client secret matches //console.log(user.secret + " => " + auth_secret);
if (user.secret !== auth_secret) {
res.format({
'text/plain': function () {
res.send({success: false, message: 'Access denied, invalid client secret!'});
},
});
} else {
// return the information including token as JSON
res.setHeader("Access-Control-Allow-Origin", config.site.origin);
res.setHeader("Access-Control-Allow-Methods", " GET, POST, PUT, DELETE");
res.setHeader ("Content-Type", "application/json");
// if user is found and password is right and code is received exchange token
/* console.log(req.query);
console.log( 'authtype: ' + auth_type);
console.log( 'Resoponse type: ' + response_type);
console.log( 'authsecret:' + auth_secret );
console.log( user);
console.log('Code: ' + code);
*/
//console.log(typeof user !== 'undefined' && typeof auth_secret !== "undefined" && auth_secret === md5(user.pass) );
if (typeof user !== 'undefined' && typeof auth_secret !== "undefined" && auth_secret === user.secret && typeof code === "undefined" && response_type === "code") { //satisfies Auth code requirements ?
var loc = ruri + '?code=' + config.api['secret'] ;
console.log(loc);
console.log(loc); //Location: "http" + (req.socket.encrypted ? "s" : "") + "://" + req.headers.host + loc,
res.writeHead(301, { Location: loc });
res.send();
} else if(typeof user !== 'undefined' && typeof code !== "undefined" && code === config.api['secret'] && auth_type == "authorization_code") { //All OK, send the token
var token = jwt.sign(user, code, {//app.get('superSecret'), { //Generate token
expiresIn: config.api.auth_duration // expires in 5 seconds
});
console.log("sending access/refresh response...");
switch(token_type) {
case "refresh_token": // do something here for refresh token
res.send({
success: true, grant_type: 'authorization_code',
message: 'Authorization expires in ' + config.api.auth_duration + ' seconds.',
refresh_token: token,
lifetime: config.api.auth_duration,
});
break;
default: // It must access token
res.send({
success: true, grant_type: 'authorization_code',
message: 'Authorization expires in ' + config.api.auth_duration + ' seconds.',
access_token: token,
lifetime: config.api.auth_duration,
});
}
} else if(typeof access_token !== 'undefined' && token_type === "refresh_token") {
res.send({
success: true, grant_type: 'authorization_code',
message: 'Authorization expires in ' + config.api.auth_duration + ' seconds.',
access_token: access_token,
lifetime: config.api.auth_duration,
});
} else {
res.send({
success: false,// c: code, usertoken: user.token,
message : "Authentication error occurred. Please try again!",
error: 'Unknown error.',
});
}
}
}
});
}
/*
* View Log
* METHOD : GET
*/
app.get('/logs', function(req, res) {
ReqLog.find({}, function (err, log) {
res.format({
'text/plain': function () { //res.send({success: false, message: 'Failed processing request, try again!'});
if (err) res.send({success: false, message: 'Failed processing request, try again!'});
else
//log.forEach(function(u) {u.pass = u.secret = u.token = 'forbidden'; });
res.send(JSON.stringify({success: true, message: "Request successful!" , data : log }));
},
});
});
});
/* --------------------------------------------------
* API Routes
*
*/
/*
// route to show a random message (GET http://localhost:8080/api/)
apiRoutes.get('/', function(req, res) {
res.json({ message: 'SHH Networks - API' });
});
*/
// apply the routes to our application with the prefix /api
app.use('/api', apiRoutes);
app.use('/bitcoind', btcRoutes);
console.log('authorization server started at http://localhost:' + https_port);