Merge remote-tracking branch 'origin/developer' into developer
This commit is contained in:
commit
83d1d4dea8
@ -1,15 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
//const Schema = mongoose.Schema,
|
||||
//ObjectId = Schema.ObjectId;
|
||||
|
||||
const MessageSchema = mongoose.Schema({
|
||||
subject: { type: String, required: true },
|
||||
message: { type: String, required: true },
|
||||
user: { type: String, required: true },
|
||||
tag: [{type: String }],
|
||||
//createtime: { type: Date, default: Date.now },
|
||||
});
|
||||
MessageSchema.index({tag:'text'});
|
||||
|
||||
module.exports = mongoose.model('Message', MessageSchema);
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
url: 'mongodb://localhost:27017/mydb'
|
||||
}
|
@ -58,8 +58,8 @@
|
||||
|
||||
<!-- NOTE: Load JQuery, Vue.js, VueRouter, Vuetify -->
|
||||
<script src="lib/jquery-3.3.1.min.js"></script>
|
||||
<script src="lib/vue.js"></script>
|
||||
<script src="lib/vue-router.js"></script>
|
||||
<script src="lib/vue-2.6.10.js"></script>
|
||||
<script src="lib/vue-router-3.0.1.js"></script>
|
||||
|
||||
<!-- Buefy/Vuetify -->
|
||||
<script src="lib/buefy-0.7.5.js"></script>
|
||||
@ -84,6 +84,7 @@
|
||||
<script src="routes/profil.js"></script>
|
||||
<script src="routes/msgCard.js"></script>
|
||||
<script src="routes/messageData.js"></script>
|
||||
<script src="routes/tagData.js"></script>
|
||||
<script src="routes/profilCard.js"></script>
|
||||
<script src="routes/profilData.js"></script>
|
||||
<script src="routes/login.js"></script>
|
||||
@ -97,12 +98,36 @@
|
||||
<div class="om-header-container">
|
||||
<div class="om-header">
|
||||
<a class="logo-img" href="index.html"><img src="img/app_icon.png" width=45px height=45px></a>
|
||||
<form class="om-searchbar">
|
||||
<form class="om-searchbar" @submit.prevent="search()">
|
||||
<b-field>
|
||||
<b-input placeholder="Suche..."
|
||||
type="search"
|
||||
icon="magnify">
|
||||
</b-input>
|
||||
<b-autocomplete
|
||||
rounded
|
||||
v-model="searchtext"
|
||||
@keydown.native.enter="search"
|
||||
:data="filteredDataArray"
|
||||
placeholder="suche..."
|
||||
icon="magnify"
|
||||
@select="option => selected = option">
|
||||
</b-autocomplete>
|
||||
|
||||
<!--<b-input
|
||||
type="search"
|
||||
v-model="searchtext"
|
||||
icon="magnify"
|
||||
placeholder="Suche...">
|
||||
</b-input>-->
|
||||
<!--<b-taginput
|
||||
id="search-text"
|
||||
type="search"
|
||||
v-model="selected"
|
||||
:data=taglist
|
||||
autocomplete
|
||||
allow-new:true
|
||||
icon="magnify"
|
||||
placeholder="Suche.."
|
||||
@typing="getFilteredTags"
|
||||
@input="saveTagsToArray">
|
||||
</b-taginput>-->
|
||||
</b-field>
|
||||
</form>
|
||||
</div>
|
||||
@ -161,6 +186,12 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var tagArray = ["lorem"];
|
||||
const dat=[
|
||||
'th',
|
||||
'efi',
|
||||
'wichtig',
|
||||
];
|
||||
|
||||
const routes = [
|
||||
{ path: "/", component: HomeRouter },
|
||||
@ -179,11 +210,127 @@
|
||||
var app = new Vue({
|
||||
router,
|
||||
el: '#api',
|
||||
data: {
|
||||
data: function() {
|
||||
return{
|
||||
searchtext: "",
|
||||
selected: [],
|
||||
taglist: dat,
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
filteredDataArray() {
|
||||
return this.taglist.filter((option) => {
|
||||
return option
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(this.searchtext.toLowerCase()) >= 0
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
search: function() {
|
||||
console.log("Searchtext: " +this.searchtext.replace(/#/g,''));
|
||||
$.ajax({
|
||||
url: "api/msg/search/" + this.searchtext.replace(/#/g, ''),
|
||||
method: "GET"
|
||||
}).done(jd => {
|
||||
// NICHT SO wg. Vue: _messagelist = jd;
|
||||
_messagelist.splice(0, _messagelist.length);
|
||||
_messagelist.push.apply(_messagelist, jd);
|
||||
//console.log("jd: "+jd);
|
||||
for (var e in jd) {
|
||||
if (!_messages[jd[e]]) {
|
||||
get_insert_message(jd[e]);
|
||||
}
|
||||
}
|
||||
}).fail(function(e, f, g) {
|
||||
console.log("searching: err: " + e + f + g);
|
||||
})
|
||||
},
|
||||
getFilteredTags(text) {
|
||||
this.taglist = dat.filter((option) => {
|
||||
return option
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(text.toLowerCase()) >= 0
|
||||
})
|
||||
this.search();
|
||||
},
|
||||
saveTagsToArray: function() {
|
||||
tagArray = this.selected;
|
||||
console.info(tagArray);
|
||||
},
|
||||
list_tags: function () {
|
||||
$.ajax({url: "api/tag/ids",method: "GET"})
|
||||
.done(jd => {
|
||||
// NICHT SO wg. Vue: _messagelist = jd;
|
||||
_taglist.splice(0, _taglist.length);
|
||||
_taglist.push.apply(_taglist, jd);
|
||||
console.log("tag: jd: " + jd);
|
||||
for (var e in jd) {
|
||||
if (!_tags[jd[e]]) {
|
||||
get_insert_tag(jd[e]);
|
||||
}
|
||||
}
|
||||
}).fail(function (e, f, g) {
|
||||
console.log("err: " + e + f + g);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
mounted: function () {
|
||||
this.search();
|
||||
this.list_tags();
|
||||
},
|
||||
});
|
||||
function get_insert_tag(id){
|
||||
$.ajax({ url: "api/tag/"+id, method: "GET" }).done(function (tag) {
|
||||
dat.push("#"+tag.name);
|
||||
console.log("it worked!");
|
||||
}).fail(function (e, f, g) {
|
||||
console.log("cannot load " + id + ".json: " + e + f + g);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
const search_data = [];
|
||||
/*
|
||||
export.default {
|
||||
data: function () {
|
||||
return {
|
||||
selected: [],
|
||||
taglist: data,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filteredTagArray() {
|
||||
this.taglist = data.filter((option) => {
|
||||
return option
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(this.name.toLowerCase()) >= 0
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
evaluate(text) {
|
||||
this.taglist = data.filter((option) => {
|
||||
return option
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(text.toLowerCase()) >= 0
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted: function () {
|
||||
if ($(this).bootstrapMaterialDesign)
|
||||
$(this).bootstrapMaterialDesign();
|
||||
},
|
||||
};
|
||||
*/
|
||||
|
||||
</script>
|
||||
|
||||
<!-- CDN_Vue.js minified lib -->
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// Wait until page loaded
|
||||
window.addEventListener('load', () => {
|
||||
if ('serviceWorker' in navigator) {
|
||||
/*if ('serviceWorker' in navigator) {
|
||||
// NOTE: ServiceWorker Registration
|
||||
return navigator.serviceWorker.register('serviceWorker.js', {
|
||||
scope: '/'
|
||||
@ -16,7 +16,7 @@ window.addEventListener('load', () => {
|
||||
} else {
|
||||
console.log('[ServiceWorker] are not supported.');
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
});
|
||||
|
||||
// NOTE: Set Bootstrap materialdesign
|
||||
|
@ -1,7 +1,8 @@
|
||||
var tagArray = [];
|
||||
const data=[
|
||||
'#th',
|
||||
'#efi',
|
||||
'#wichtig',
|
||||
'th',
|
||||
'efi',
|
||||
'wichtig',
|
||||
];
|
||||
const CreateMsgRouter = {
|
||||
template: `
|
||||
@ -18,13 +19,15 @@ const CreateMsgRouter = {
|
||||
|
||||
<b-field label="Tags">
|
||||
<b-taginput
|
||||
id="tag"
|
||||
v-model="selected"
|
||||
:data=items
|
||||
:data=taglist
|
||||
autocomplete
|
||||
allow-new:false
|
||||
icon="label"
|
||||
placeholder="#"
|
||||
@typing="getFilteredTags" id="tag">
|
||||
@typing="getFilteredTags"
|
||||
@input="saveTagsToArray">
|
||||
</b-taginput>
|
||||
</b-field>
|
||||
|
||||
@ -33,38 +36,41 @@ const CreateMsgRouter = {
|
||||
</b-field>
|
||||
|
||||
<b-button @click="$router.go(-1)">ABBRECHEN</b-button>
|
||||
<b-button type="is-primary" @click="$router.push('/home')">SENDEN</b-button>
|
||||
|
||||
|
||||
<b-button type="is-primary" @click="createMsg">SENDEN</b-button>
|
||||
|
||||
</div>
|
||||
`,
|
||||
data: function () {
|
||||
return {
|
||||
selected: [],
|
||||
items: data
|
||||
taglist: data,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
saveTagsToArray: function() {
|
||||
tagArray = this.selected;
|
||||
console.info(tagArray);
|
||||
},
|
||||
createMsg: function () {
|
||||
var subject = $("#subject").val();
|
||||
var message = $("#message").val();
|
||||
var tag = $("#tag").val();
|
||||
var user = $("#user").val();
|
||||
console.log("Message Created: " + tag + " " + message + " " + user);
|
||||
var _subject = $("#subject").val();
|
||||
var _message = $("#message").val();
|
||||
var _tag = tagArray;
|
||||
var _user = $("#user").val();
|
||||
//console.log("Message Created: " + _tag + " " + _message + " " + _user);
|
||||
$.ajax({
|
||||
url: "api/createMsg",
|
||||
url: "api/msg",
|
||||
data: {
|
||||
sub: subject,
|
||||
mess: message,
|
||||
use: user,
|
||||
ta: tag
|
||||
subject: _subject,
|
||||
message: _message,
|
||||
user: _user,
|
||||
tag: _tag
|
||||
},
|
||||
method: "POST"
|
||||
}).done(have_result).fail(have_error);
|
||||
|
||||
function have_result(res) {
|
||||
console.log(res);
|
||||
//console.log(res);
|
||||
router.push('/home')
|
||||
}
|
||||
|
||||
function have_error(err) {
|
||||
@ -73,16 +79,42 @@ const CreateMsgRouter = {
|
||||
}
|
||||
},
|
||||
getFilteredTags(text) {
|
||||
this.items = data.filter((option) => {
|
||||
this.taglist = data.filter((option) => {
|
||||
return option
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(text.toLowerCase()) >= 0
|
||||
})
|
||||
},
|
||||
},
|
||||
list_tags: function () {
|
||||
$.ajax({url: "api/tag/ids",method: "GET"})
|
||||
.done(jd => {
|
||||
// NICHT SO wg. Vue: _messagelist = jd;
|
||||
_taglist.splice(0, _taglist.length);
|
||||
_taglist.push.apply(_taglist, jd);
|
||||
console.log("tag: jd: " + jd);
|
||||
for (var e in jd) {
|
||||
if (!_tags[jd[e]]) {
|
||||
get_insert_tag(jd[e]);
|
||||
}
|
||||
}
|
||||
}).fail(function (e, f, g) {
|
||||
console.log("err: " + e + f + g);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.list_tags();
|
||||
if ($(this).bootstrapMaterialDesign)
|
||||
$(this).bootstrapMaterialDesign();
|
||||
},
|
||||
};
|
||||
|
||||
function get_insert_tag(id){
|
||||
$.ajax({ url: "api/tag/"+id, method: "GET" }).done(function (tag) {
|
||||
data.push("#" + tag.name);
|
||||
console.log("Array:"+this.data);
|
||||
}).fail(function (e, f, g) {
|
||||
console.log("cannot load " + id + ".json: " + e + f + g);
|
||||
})
|
||||
}
|
||||
|
@ -24,12 +24,12 @@ const HomeRouter = {
|
||||
});
|
||||
},*/
|
||||
list_messages: function () {
|
||||
$.ajax({url: "api/ids", method: "GET"})
|
||||
$.ajax({url: "api/msg/ids", method: "GET"})
|
||||
.done(jd => {
|
||||
// NICHT SO wg. Vue: _messagelist = jd;
|
||||
_messagelist.splice(0, _messagelist.length);
|
||||
_messagelist.push.apply(_messagelist, jd);
|
||||
console.log("jd: "+jd);
|
||||
//console.log("jd: "+jd);
|
||||
for (var e in jd) {
|
||||
if (!_messages[jd[e]]) {
|
||||
get_insert_message(jd[e]);
|
||||
@ -49,7 +49,7 @@ const HomeRouter = {
|
||||
}
|
||||
}*/
|
||||
}).fail(function (e, f, g) {
|
||||
console.log("err: " + e + f + g);
|
||||
console.log("list_msg: err: " + e + f + g);
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -61,7 +61,7 @@ const HomeRouter = {
|
||||
};
|
||||
|
||||
function get_insert_message(id) {
|
||||
$.ajax({ url: "api/msg/"+id, method: "GET" }).done(function (msg) {
|
||||
$.ajax({ url: "api/msg/id/"+id, method: "GET" }).done(function (msg) {
|
||||
Vue.set(_messages, id, msg);
|
||||
}).fail(function (e, f, g) {
|
||||
console.log("cannot load " + id + ".json: " + e + f + g);
|
||||
|
@ -5,7 +5,8 @@ Vue.component('MsgCard', {
|
||||
<img src="favicon.ico" width=20px height=20px>
|
||||
</h6>
|
||||
{{ msg.message }}<br><br>
|
||||
<a href="#">{{ msg.tag }}</a></p>
|
||||
<a v-for="tag in msg.tag" href="#">#{{ tag }} </a>
|
||||
</p>
|
||||
<div class="om-card-footer"> <div class="om-user-line">
|
||||
<i class="material-icons">account_circle</i>
|
||||
Erstellt von {{ msg.user }}</div>
|
||||
|
2
public/routes/tagData.js
Normal file
2
public/routes/tagData.js
Normal file
@ -0,0 +1,2 @@
|
||||
_taglist = [];
|
||||
_tags = [];
|
362
server.js
362
server.js
@ -1,230 +1,176 @@
|
||||
// Original file created by Prof.Dr. Matthias Hopf
|
||||
|
||||
/**
|
||||
* Express based http & https server
|
||||
*
|
||||
* Requires express >= 4
|
||||
*/
|
||||
|
||||
var common = require('./server/common'),
|
||||
authorize = require('./server/authorization'),
|
||||
dbs = require('./server/dbs');
|
||||
/*
|
||||
var common = require ('./server/common'),
|
||||
authorize = require ('./server/authorization'),
|
||||
dbs = require ('./server/dbs'),
|
||||
files = require ('./server/files');
|
||||
*/
|
||||
var fs = require ('fs'),
|
||||
http = require ('http'),
|
||||
https = require ('https'),
|
||||
express = require ('express'),
|
||||
session = require ('express-session'), // session management
|
||||
morgan = require ('morgan'), // logger
|
||||
//serveFavicon = require ('serve-favicon'),
|
||||
bodyParser = require ('body-parser');
|
||||
//MongoStore = require ('connect-mongo')(session); // uss mongodb as session storage
|
||||
var Message = require('./message.model.js');
|
||||
const fs = common.fs, // file sync, read certificates
|
||||
http = common.http, // http handler
|
||||
https = require('https'), // https handler
|
||||
express = require('express'), // node server framework
|
||||
session = require('express-session'), // session management (security)
|
||||
morgan = require('morgan'), // logger
|
||||
mong = common.mongoose, // mongoose
|
||||
// serveFavicon = require('serve-favicon'), // provide favicon
|
||||
bodyParser = require('body-parser'), // post request bodyparser
|
||||
MongoStore = require('connect-mongo')(session); // use mongodb as session storage
|
||||
|
||||
var app = express();
|
||||
|
||||
var http_port=8013;
|
||||
https_port=8889;
|
||||
|
||||
/*
|
||||
* Init
|
||||
*/
|
||||
/*ll
|
||||
common .init ();
|
||||
authorize.init (common);
|
||||
common .init();
|
||||
authorize .init(common);
|
||||
dbs .init (common);
|
||||
files .init (common);
|
||||
*/
|
||||
//files .init (common);
|
||||
mong.Promise = global.Promise;
|
||||
|
||||
// Security
|
||||
app.disable ('x-powered-by'); // TODO: Disable Header information: Powerd by Express -> Information disclosure
|
||||
/*
|
||||
* Security
|
||||
*
|
||||
* TODO: Install helmet
|
||||
* https://expressjs.com/de/advanced/best-practice-security.html
|
||||
*
|
||||
* (Disable Header information: Powerd by Express)
|
||||
* -> Information disclosure
|
||||
*/
|
||||
app.disable('x-powered-by');
|
||||
|
||||
|
||||
/*
|
||||
* Route Control
|
||||
*/
|
||||
|
||||
// Logger
|
||||
app.use (morgan ('dev'));
|
||||
//app.use(express.logger ( { format: 'default', stream: output_stream } ));
|
||||
|
||||
// Fastpaths
|
||||
//app.use (serveFavicon (__dirname + '/public/favicon.ico'));
|
||||
|
||||
// Session Management
|
||||
app.use (session({
|
||||
secret: 'adluhohks',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: {
|
||||
maxAge: 30*24*3600*1000, // TODO: ttl for session as well (Store)
|
||||
secure: false, // true for https only
|
||||
},
|
||||
name: 'om.sid',
|
||||
//store: new MongoStore ({mongooseConnection: dbs.mongoose.connection, ttl: 30*24*3600}), // mongoose + connect-mongo
|
||||
//store: new MemoryStore ({checkPeriod: 24*3600*1000}), // memorystore
|
||||
app.set('trust proxy', 1) // trust first proxy, neccessary for cookie secure: true flag
|
||||
app.use(session({
|
||||
secret: 'ahhgylhuvh', // caesar(3) 2 letter surname
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: {
|
||||
maxAge: 30 * 24 * 3600 * 1000, // TODO: ttl for session as well (Store)
|
||||
secure: true, // true for https only (since our app works only with https)
|
||||
},
|
||||
name: 'om.sid',
|
||||
store: new MongoStore({
|
||||
mongooseConnection: mong.connection,
|
||||
ttl: 30 * 24 * 3600
|
||||
}), // mongoose + connect-mongo
|
||||
//store: new MemoryStore ({checkPeriod: 24*3600*1000}), // memorystore
|
||||
}));
|
||||
|
||||
// Args
|
||||
app.use (bodyParser.json());
|
||||
app.use (bodyParser.urlencoded({extended: true}));
|
||||
// TODO Favicon for Desktop
|
||||
//app.use (serveFavicon (__dirname + '/public/favicon.ico'));
|
||||
|
||||
// Minimal Logging
|
||||
//app.use (morgan ('dev'));
|
||||
// Advanced Logging
|
||||
morgan.token('user', function (req, res) {
|
||||
return (req.session && req.session.user) || '-';
|
||||
});
|
||||
morgan.token('userColored', function (req, res) {
|
||||
var color = 0;
|
||||
if (req.session && req.session.roles)
|
||||
color = req.session.roles.admin ? 31 // red
|
||||
: req.session.roles.user ? 34 // blue
|
||||
: 0; // no color
|
||||
return '\x1b[' + color + 'm' + ((req.session && req.session.user) || '-') + '\x1b[0m';
|
||||
});
|
||||
morgan.token('statusColored', function (req, res) {
|
||||
var color = res.statusCode >= 500 ? 31 // red
|
||||
: res.statusCode >= 400 ? 33 // yellow
|
||||
: res.statusCode >= 300 ? 36 // cyan
|
||||
: res.statusCode >= 200 ? 32 // green
|
||||
: 0; // no color
|
||||
return '\x1b[' + color + 'm' + (res.headersSent ? res.statusCode : '-') + '\x1b[0m';
|
||||
});
|
||||
app.use(morgan(':date[iso] :statusColored :method :url :userColored :response-time ms :res[content-length]'));
|
||||
|
||||
// BodyParser
|
||||
// Returns middleware that only parses json bodies.
|
||||
// (https://www.npmjs.com/package/body-parser#bodyparserjsonoptions)
|
||||
app.use(bodyParser.json());
|
||||
// Returns middleware that only parses urlencoded bodies
|
||||
// with qs library (https://www.npmjs.com/package/qs#readme)
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
|
||||
// API
|
||||
//var api_routes = express.Router(); // express app-object routing
|
||||
//app.use ('/api', api_routes);
|
||||
var api_routes = express.Router(); // express app-object routing
|
||||
app.use('/api', api_routes);
|
||||
|
||||
app.use (function (req, res, done) {
|
||||
console.log(req.url);
|
||||
done();
|
||||
});
|
||||
|
||||
//global.__basedir = __dirname;
|
||||
|
||||
// Static Files
|
||||
app.use(express.static(__dirname + '/public')); // Allow server access to 'public' folder
|
||||
|
||||
//app.use(express.static('resources'));
|
||||
|
||||
// Configuring the database
|
||||
var dbConfig = require('./mongodb.config.js');
|
||||
var mongoose = require('mongoose');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
|
||||
// Connecting to the database
|
||||
//mongoose.connect(`mongodb://${server}/${dbConfig.url}`)
|
||||
mongoose.connect(dbConfig.url, {useNewUrlParser: true}).then(() => {
|
||||
console.log("Successfully connected to MongoDB.");
|
||||
}).catch(err => {
|
||||
console.log('Could not connect to MongoDB.');
|
||||
process.exit();
|
||||
});
|
||||
|
||||
|
||||
//require('./app/routes/message.route.js')(app);
|
||||
|
||||
app.get ('/api/ids', function (req, res) {
|
||||
Message.find({},{id: true}) .exec () .then(results => {
|
||||
//selects id from message:
|
||||
var parsed = [];
|
||||
for (var i in results) {
|
||||
parsed.push (results[i].id);
|
||||
}
|
||||
//var parsed = results.map (x => x._id);
|
||||
res.send(parsed);
|
||||
} )
|
||||
.catch(err => {
|
||||
console.log (err);
|
||||
res .status(500) .json (err);
|
||||
});
|
||||
});
|
||||
|
||||
app.get ("/api/msg/:id", function (req, res) {
|
||||
Message.findOne ({_id: req.params.id}) .exec (function (err, results){
|
||||
if (err) {
|
||||
console.log (err);
|
||||
res .status(404) .json (err);
|
||||
} else {
|
||||
console.log(JSON.stringify(results));
|
||||
res.json(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/*app.get ("/api/msg/search/:phrase", function (req, res) {
|
||||
Message.find ({$text: {$search: req.params.phrase}) .then (function (err, results){
|
||||
if (err) {
|
||||
console.log (err);
|
||||
res .status(404) .json (err);
|
||||
} else {
|
||||
console.log(JSON.stringify(results));
|
||||
res.json(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
*/
|
||||
/*function makeid() {
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
|
||||
return text;
|
||||
}*/
|
||||
|
||||
app.post("/api/createMsg", function(req, res){
|
||||
//x = mongoose.Types.ObjectId();
|
||||
//y = x.toString();
|
||||
//var z = makeid();
|
||||
console.log("SUbject: "+JSON.stringify(req.body));
|
||||
var message = new Message( {subject: req.body.sub, message: req.body.mess, user: req.body.use, tag: req.body.ta } );
|
||||
|
||||
message.save(function(err,result){
|
||||
if(err){
|
||||
return res .status(401) .send(err.message);
|
||||
}else{
|
||||
res.json({message: "Message created!!"});
|
||||
}
|
||||
});
|
||||
});
|
||||
// Static Files - Allow access to 'public' folder
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// Other stuff is NOT authorized unless logged in
|
||||
//app.use (authorize.genCheckAuthorized ('user'));
|
||||
|
||||
// Uploaded files
|
||||
//app.use ('/uploads', expr ess.static(__dirname + '/uploads'));
|
||||
|
||||
// Other stuff is NOT authorized unless logged in
|
||||
//app.use (authorize.genCheckAuthorized ('user'));
|
||||
|
||||
// Uploaded files
|
||||
//app.use ('/uploads', express.static(__dirname + '/uploads'));
|
||||
|
||||
// Errors
|
||||
// No error so far? Then it's a 404!
|
||||
//app.use (function (req, res, next) { next (common.genError (404, req.url)); });
|
||||
//app.use (routes.errorHandler (true)); /* true: show stack traces */ // TODO: Error Handler
|
||||
|
||||
app.use(function (req, res, next) {
|
||||
next(common.genError(404, req.url));
|
||||
});
|
||||
//app.use (routes.errorHandler (true)); /* true: show stack traces */
|
||||
|
||||
/*
|
||||
* API
|
||||
*/
|
||||
/*
|
||||
// API allowed for all
|
||||
api_routes.post ('/login', authorize.login); // /api/login
|
||||
api_routes.post('/login', authorize.login);
|
||||
|
||||
// Validate all other API calls
|
||||
api_routes.use (authorize.genCheckAuthorized ('user'));
|
||||
api_routes.post ('/logout', authorize.logout);
|
||||
//api_routes.use(authorize.genCheckAuthorized('user'));
|
||||
api_routes.post('/logout', authorize.logout);
|
||||
|
||||
function addRoutes (r) {
|
||||
for (var e in r.routes) {
|
||||
var params = r.routes[e].params ? "/" + r.routes[e].params : "";
|
||||
console.log ("Adding routes for /" + e + params + ":" +
|
||||
(r.routes[e].get ? " get":" ") + (r.routes[e].post ? " post":" ") +
|
||||
(r.routes[e].put ? " put":" ") + (r.routes[e].delete ? " delete":" "));
|
||||
if (r.routes[e].get)
|
||||
api_routes.get ('/' + e + params, r.routes[e].get);
|
||||
if (r.routes[e].post)
|
||||
api_routes.post ('/' + e + params, r.routes[e].post);
|
||||
if (r.routes[e].put)
|
||||
api_routes.put ('/' + e + params, r.routes[e].put);
|
||||
if (r.routes[e].delete)
|
||||
api_routes.delete ('/' + e + params, r.routes[e].delete);
|
||||
}
|
||||
// Add API routes
|
||||
function addRoutes(r) {
|
||||
for (var e in r.routes) {
|
||||
var route = '/' + e + (r.routes[e].params ? "/" + r.routes[e].params : "");
|
||||
var log = "Adding routes for " + route + ":";
|
||||
/*
|
||||
var auth = r.routes[e].auth || r.auth;
|
||||
if (auth) {
|
||||
log += " [auth]";
|
||||
api_routes.use (route, function (req, res, next) {
|
||||
if (! auth(req))
|
||||
return next (common.genError (403, "Unauthorized"));
|
||||
next ();
|
||||
});
|
||||
}
|
||||
*/
|
||||
/*
|
||||
var role = r.routes[e].role || r.role;
|
||||
if (role) {
|
||||
log += " [role:"+role+"]";
|
||||
api_routes.use (route, authorize.genCheckAuthorized (role));
|
||||
}
|
||||
*/
|
||||
const methods = ["get", "post", "put", "delete"];
|
||||
for (var m in methods) {
|
||||
if (r.routes[e][methods[m]]) {
|
||||
log += " " + methods[m];
|
||||
api_routes[methods[m]](route, r.routes[e][methods[m]]);
|
||||
}
|
||||
}
|
||||
console.log(log);
|
||||
}
|
||||
}
|
||||
|
||||
addRoutes (dbs);
|
||||
addRoutes (files);
|
||||
*/
|
||||
addRoutes(dbs);
|
||||
|
||||
/*
|
||||
* Servers
|
||||
*/
|
||||
|
||||
http.createServer (app) .listen (http_port, function () {
|
||||
console.log ("Express http server listening on port " + http_port);
|
||||
http.createServer(app).listen(common.config.httpPort, function () {
|
||||
console.log("Express http server listening on port " + common.config.httpPort);
|
||||
});
|
||||
|
||||
/*
|
||||
@ -238,39 +184,37 @@ http.createServer (app) .listen (http_port, function () {
|
||||
* openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
|
||||
* rm certrequest.csr
|
||||
*/
|
||||
|
||||
var options;
|
||||
try {
|
||||
try {
|
||||
// In case it's a real certificate: add CA chain cersts (TODO: use array if required)
|
||||
var ca = fs.readFileSync ('keys/ca_cert.pem');
|
||||
} catch (e) {
|
||||
ca = undefined;
|
||||
console.log ("Note: Can't read CA bundle: "+e);
|
||||
}
|
||||
if (ca != null) {
|
||||
|
||||
options = {
|
||||
key: fs.readFileSync ('keys/omkey.pem'),
|
||||
cert: fs.readFileSync ('keys/certificate.pem'),
|
||||
ca: ca
|
||||
};
|
||||
https.createServer (options, app) .listen (https_port, function () {
|
||||
console.log ("Express https server listening on port " + https_port);
|
||||
});
|
||||
if (common.config.httpsPort) {
|
||||
var options;
|
||||
try {
|
||||
try {
|
||||
// In case it's a real certificate: add CA chain cersts (TODO: use array if required)
|
||||
var ca = fs.readFileSync('keys/ca_cert.pem');
|
||||
} catch (e) {
|
||||
ca = undefined;
|
||||
console.log("Note: Can't read CA bundle: " + e);
|
||||
}
|
||||
if (ca != undefined) {
|
||||
options = {
|
||||
key: fs.readFileSync('keys/omkey.pem'),
|
||||
cert: fs.readFileSync('keys/certificate.pem'),
|
||||
ca: ca
|
||||
};
|
||||
https.createServer(options, app).listen(common.config.httpsPort, function () {
|
||||
console.log("Express https server listening on port " + common.config.httpsPort);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Note: Can't read SSL keys/certs: " + e + "\nDisabling https server");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log ("Note: Can't read SSL keys/certs: "+e+"\nDisabling https server");
|
||||
} else {
|
||||
console.log("Note: https server disabled by config");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Uncaught Exceptions
|
||||
*/
|
||||
|
||||
process.on ("uncaughtException", function (err) {
|
||||
console.error ("*** Uncaught Exception:");
|
||||
console.error (err.stack);
|
||||
process.on("uncaughtException", function (err) {
|
||||
console.error("*** Uncaught Exception:");
|
||||
console.error(err.stack);
|
||||
});
|
||||
|
||||
|
||||
|
118
server/authorization.js
Normal file
118
server/authorization.js
Normal file
@ -0,0 +1,118 @@
|
||||
// Original file created by Prof.Dr. Matthias Hopf
|
||||
|
||||
/*
|
||||
* Authorization
|
||||
*/
|
||||
var common, User;
|
||||
const ldap = require ('./ldap_ohm'),
|
||||
crypto = require ("../server/crypto");
|
||||
|
||||
// deactivated is not used yet
|
||||
const serverVisibleSession = { user: true, name: true, type: true, mail: true, roles: true, deactivated: true, host: true };
|
||||
const clientVisibleSession = { user: true, name: true, type: true, mail: true, roles: true };
|
||||
|
||||
|
||||
// Fill in session object
|
||||
function fillSession (req, user, roles, cb) {
|
||||
if (req.session === undefined)
|
||||
next (common.genError (500, "Error"));
|
||||
req.session.regenerate (function (err) {
|
||||
if (user !== undefined && ! err) {
|
||||
common.shallowCopy (user, serverVisibleSession, {roles: true}, req.session);
|
||||
if (user._id) {
|
||||
req.session.user = user._id;
|
||||
}
|
||||
req.session.roles = roles;
|
||||
}
|
||||
return cb (err);
|
||||
});
|
||||
}
|
||||
|
||||
const authorization = {
|
||||
// Generate Error object suitible for throwing or next()ing
|
||||
genCheckAuthorized: function (group) {
|
||||
return function (req, res, next) {
|
||||
if (req.session === undefined || req.session.user === undefined ||
|
||||
req.session.roles === undefined)
|
||||
return next (common.genError (403, "Unauthorized"));
|
||||
if (req.session.roles[group] === undefined)
|
||||
return next (common.genError (403, "Unauthorized"));
|
||||
next ();
|
||||
}
|
||||
},
|
||||
|
||||
// Login route: requires .user and .pwd params
|
||||
login: function (req, res, next) {
|
||||
var user = req.body.user || '';
|
||||
var pwd = req.body.pwd || '';
|
||||
|
||||
// Helper: Return valid session Object
|
||||
function returnSession () {
|
||||
// Only export client visible parts of session object
|
||||
var copy = common.shallowCopy (req.session, clientVisibleSession);
|
||||
return res.json (copy);
|
||||
}
|
||||
// Helper: Return error
|
||||
function returnError () {
|
||||
fillSession (req, undefined, undefined, function (err) {
|
||||
next (common.genError (401, "Unauthorized"));
|
||||
});
|
||||
}
|
||||
|
||||
// TODO Auth: validate session ID
|
||||
// Check whether to just validate current session ID
|
||||
if (user === '' && pwd === '') {
|
||||
console.log ("auth revalidate: " + req.session.user);
|
||||
if (req.session.user === undefined)
|
||||
return returnError();
|
||||
return returnSession ();
|
||||
}
|
||||
/*
|
||||
// check local database, then ldap
|
||||
User.findById (req.body.user) .exec (function (err, entry) {
|
||||
// If there is a local user AND it has a password associated, test against this, and only this
|
||||
if (entry != null && entry.pwd) {
|
||||
if (crypto.checkLocalAuth (entry, req.body.pwd)) {
|
||||
return fillSession (req, entry, common.arrayToHash(entry.roles), returnSession);
|
||||
}
|
||||
return returnError ();
|
||||
}
|
||||
|
||||
// check ldap
|
||||
ldap.authorize (user.toLowerCase(), pwd, function (found) {
|
||||
console.log ("ldap authorize " + user + " returns " + JSON.stringify (found));
|
||||
// No ldap entry either -> unauthorized
|
||||
if (found == null) {
|
||||
return returnError ();
|
||||
}
|
||||
// If there is an entry w/o password, use it for roles etc.
|
||||
if (entry) {
|
||||
if (! entry.name || entry.name === "")
|
||||
entry.name = found.name;
|
||||
if (! entry.mail || entry.mail === "")
|
||||
entry.mail = found.mail;
|
||||
if (! entry.type || entry.type === "")
|
||||
entry.type = found.type;
|
||||
if (! entry.orclgender || entry.orclgender === "")
|
||||
entry.orclgender = found.orclgender;
|
||||
return fillSession (req, entry, entry.roles.length > 0 ? common.arrayToHash(entry.roles) : {user:true}, returnSession);
|
||||
}
|
||||
// Otherwise create standard user entry
|
||||
return fillSession (req, found, {user:true}, returnSession);
|
||||
});
|
||||
});*/
|
||||
},
|
||||
logout: function (req, res, next) {
|
||||
fillSession (req, undefined, undefined, function (err) {
|
||||
return res.json ({});
|
||||
});
|
||||
},
|
||||
init: function (_common) {
|
||||
common = _common;
|
||||
ldap.init (_common);
|
||||
//User = require('../database/user.model.js');;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
module.exports = authorization;
|
80
server/common.js
Normal file
80
server/common.js
Normal file
@ -0,0 +1,80 @@
|
||||
// Original file created by Prof.Dr. Matthias Hopf
|
||||
|
||||
/*
|
||||
* Common functions and imports
|
||||
*/
|
||||
|
||||
var common = {
|
||||
fs: require('fs'), // file sync
|
||||
http: require('http'),
|
||||
mongoose: require('mongoose'), // Needed for db connection.
|
||||
//util: require('util'), // Why is it needed here?
|
||||
//fork: require('child_process') .fork, // What does that?
|
||||
|
||||
// Generate Error object suitible for throwing or next()ing
|
||||
// For a better exception handling
|
||||
genError: function (code, message) {
|
||||
var err = new Error (common.http.STATUS_CODES[code] + (message != undefined && message != "" ? ": "+message : ""));
|
||||
err.status = code;
|
||||
// to generally disable stack traces for these manually created error Objects:
|
||||
delete err.stack;
|
||||
return err;
|
||||
},
|
||||
|
||||
// Generate deep copy
|
||||
// Only include properties incl (all if undefined), strip properties excl (associative arrays)
|
||||
deepCopy: function (inp, incl, excl) {
|
||||
// For now, JSON is considered fastest / easiest
|
||||
var obj = JSON.parse (JSON.stringify (inp));
|
||||
if (incl) {
|
||||
for (var k in obj) {
|
||||
if (incl[k] === undefined)
|
||||
delete obj[k];
|
||||
}
|
||||
}
|
||||
if (excl) {
|
||||
for (var k in excl) {
|
||||
delete obj[k];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
// Create shallow (1 level) copy of object, use obj if already present (merge)
|
||||
// Only include properties incl (all if undefined), strip properties excl (associative arrays)
|
||||
shallowCopy: function (inp, incl, excl, obj) {
|
||||
var keys = inp;
|
||||
if (obj === undefined)
|
||||
obj = {};
|
||||
if (typeof inp == "array")
|
||||
obj = [];
|
||||
if (incl !== undefined)
|
||||
keys = incl;
|
||||
for (var k in keys) {
|
||||
if (inp[k] !== undefined && (excl === undefined || ! excl[k]))
|
||||
obj[k] = inp[k];
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
// Create hash of 'true' entries for array/mongoose object
|
||||
arrayToHash: function (array) {
|
||||
var hash = {};
|
||||
for (var e=0; e < array.length; e++) {
|
||||
hash[array[e]] = true;
|
||||
}
|
||||
return hash;
|
||||
},
|
||||
|
||||
// Log output session cookie
|
||||
debug: function (req) {
|
||||
console.log ("- " + req.headers.cookie + "\n+ " + req.session.id + "\n " + JSON.stringify (req.session));
|
||||
},
|
||||
|
||||
// Init config data
|
||||
init: function () {
|
||||
this.config = JSON.parse (this.fs.readFileSync ("server_config.json"));
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = common;
|
31
server/crypto.js
Normal file
31
server/crypto.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Original file created by Prof.Dr. Matthias Hopf
|
||||
|
||||
/*
|
||||
* Crypto routines for Authorization
|
||||
*/
|
||||
|
||||
const crypto = require ("crypto");
|
||||
|
||||
const defaultHash = "sha256";
|
||||
const defaultSaltLen = 16; // More (e.g. 256) for extra paranoia
|
||||
|
||||
const mod = {
|
||||
encodePwd: function (entry, pwd) {
|
||||
return crypto.createHash (entry.hash) .update (entry.salt + ":" + pwd, 'utf8') .digest ('base64');
|
||||
},
|
||||
checkLocalAuth: function (entry, pwd) {
|
||||
if (!entry || !entry._id || !entry.hash || !entry.salt || !entry.hash || !entry.pwd ||
|
||||
!pwd || pwd === '')
|
||||
return false;
|
||||
return mod.encodePwd (entry, pwd) === entry.pwd;
|
||||
},
|
||||
fillLocalAuth: function (entry, pwd) {
|
||||
if (!entry.hash)
|
||||
entry.hash = defaultHash;
|
||||
entry.salt = crypto.randomBytes (defaultSaltLen) .toString('base64');
|
||||
entry.pwd = mod.encodePwd (entry, pwd);
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
module.exports = mod;
|
237
server/dbs.js
Normal file
237
server/dbs.js
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Main database access functions
|
||||
*/
|
||||
var common,
|
||||
model = {};
|
||||
|
||||
const dbs = {
|
||||
/* Method API route
|
||||
* <- to server
|
||||
* -> to client
|
||||
* Description
|
||||
*/
|
||||
routes: {
|
||||
"msg/ids": {
|
||||
/* GET /api/msg/ids [no args]
|
||||
* -> Array of message schema object ids
|
||||
* Get ALL known message ids
|
||||
*/
|
||||
get: function(req, res) {
|
||||
model.Messages.find({},{_id: true}).exec()
|
||||
.then(results => {
|
||||
//selects id from message:
|
||||
var parsed = [];
|
||||
for (var i in results) {
|
||||
parsed.push (results[i]._id);
|
||||
}
|
||||
res.send(parsed);
|
||||
} )
|
||||
.catch(err => {
|
||||
console.log (err);
|
||||
res.status(500).json(err);
|
||||
});
|
||||
},
|
||||
},
|
||||
"msg/id": {
|
||||
params: ":id",
|
||||
/* GET /api/msg/id/[massage-id]
|
||||
* -> Message schema
|
||||
* Get a particular message
|
||||
*/
|
||||
get: function(req, res) {
|
||||
model.Messages.findById(req.params.id) .exec(function(err, result) {
|
||||
if (err) {
|
||||
console.log (err);
|
||||
res.status(404).json(err);
|
||||
} else {
|
||||
//console.log(JSON.stringify(result));
|
||||
res.json(result);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
"msg/search": {
|
||||
params: ":phrase",
|
||||
/* GET /api/msg/id/[massage-id]
|
||||
* -> Message schema
|
||||
* Get a particular message
|
||||
*/
|
||||
get: function(req, res) {
|
||||
model.Messages.find({$text: {$search: req.params.phrase}})
|
||||
.exec().then(results => {
|
||||
//selects id from message:
|
||||
var parsed = [];
|
||||
for (var i in results) {
|
||||
parsed.push (results[i]._id);
|
||||
}
|
||||
res.send(parsed);
|
||||
} )
|
||||
.catch(err => {
|
||||
console.log (err);
|
||||
res.status(500).json(err);
|
||||
});
|
||||
},
|
||||
},
|
||||
"msg": {
|
||||
/* POST /api/msg
|
||||
* <- Message schema
|
||||
* -> Message schema
|
||||
* Create a new message
|
||||
*/
|
||||
post: function(req, res) {
|
||||
/*
|
||||
if ( !(req.body.tags instanceof Array) ) {
|
||||
return res.status(400).json({ error: "bad request" });
|
||||
}*/
|
||||
//console.log("Subject: "+JSON.stringify(req.body));
|
||||
|
||||
model.Messages.create({
|
||||
subject: req.body.subject,
|
||||
message: req.body.message,
|
||||
user: req.body.user,
|
||||
tag: req.body.tag
|
||||
}, function(err, result) {
|
||||
if (err) {
|
||||
return res.status(401).json(err.message);
|
||||
} else {
|
||||
res.json({message: "Message created!!"});
|
||||
}
|
||||
if (result == null) {
|
||||
return res.status(500).json("Can not create message.")
|
||||
}
|
||||
});
|
||||
},
|
||||
/* PUT /api/msg
|
||||
* <-
|
||||
* ->
|
||||
* Update a message
|
||||
*/
|
||||
//put: function(req, res) {},
|
||||
},
|
||||
"tag/ids": {
|
||||
/* GET /api/tag/ids [no args]
|
||||
* -> Array of tag schema object ids
|
||||
* Get ALL known tag ids
|
||||
*/
|
||||
get: function(req, res) {
|
||||
model.Tags.find({},{_id: true}).exec()
|
||||
.then(results => {
|
||||
//selects id from tag:
|
||||
var parsed = [];
|
||||
for (var i in results) {
|
||||
parsed.push (results[i]._id);
|
||||
}
|
||||
res.send(parsed);
|
||||
} )
|
||||
.catch(err => {
|
||||
console.log (err);
|
||||
res.status(500).json(err);
|
||||
});
|
||||
},
|
||||
},
|
||||
"tag": {
|
||||
params: ":id",
|
||||
/* GET /api/tag/[tag-id]
|
||||
* -> Tag schema
|
||||
* Get a particular tag
|
||||
*/
|
||||
get: function(req, res) {
|
||||
model.Tags.findById(req.params.id) .exec(function(err, result) {
|
||||
if (err) {
|
||||
console.log (err);
|
||||
res.status(404).json(err);
|
||||
} else {
|
||||
//console.log(JSON.stringify(result));
|
||||
res.json(result);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
/* Initialize requirements
|
||||
* - DB connection
|
||||
* - DB schemata
|
||||
*/
|
||||
init: function (_common) {
|
||||
common = _common;
|
||||
|
||||
/* DB Connection
|
||||
* Local db: common.config.dbLocalConn
|
||||
* TH db: common.config.dbConn
|
||||
*/
|
||||
common.mongoose.connect (common.config.dbLocalConn, {
|
||||
useNewUrlParser: true
|
||||
}).then(() => {
|
||||
console.log("Database connected successfully.");
|
||||
}).catch(err => {
|
||||
console.log('Database connection error.');
|
||||
process.exit();
|
||||
});
|
||||
|
||||
/* DB Schemata
|
||||
* Privat fields:
|
||||
* - per model: _list: Elements that are included in list fetch
|
||||
* - per entry: _comment: Comment for Admin UI - TODO: not working yet
|
||||
*/
|
||||
var messageSchema = common.mongoose.Schema({
|
||||
subject: { type: String, required: true,
|
||||
_comment: "" },
|
||||
message: { type: String, required: true,
|
||||
_comment: "" },
|
||||
user: { type: String, required: true,
|
||||
_comment: "" },
|
||||
tag: { type: [String],
|
||||
_comment: "" },
|
||||
//createtime: { type: Date, default: Date.now },
|
||||
});
|
||||
messageSchema.index({ "$**":'text' });
|
||||
model.Messages = common.mongoose.model('messages', messageSchema);
|
||||
model.Messages._list = [ "" ];
|
||||
|
||||
var tagSchema = common.mongoose.Schema({
|
||||
name: { type: String, required: true,
|
||||
_comment: "" }, //unique
|
||||
});
|
||||
model.Tags = common.mongoose.model('tags', messageSchema);
|
||||
model.Tags._list = [ "" ];
|
||||
|
||||
var userSchema = common.mongoose.Schema({
|
||||
//_id: { type: String },
|
||||
name: { type: String, required: true,
|
||||
_comment: "" },
|
||||
pwd: { type: String,
|
||||
_comment: "" },
|
||||
//hash: { type: String },
|
||||
//salt: { type: String },
|
||||
//type: { type: String },
|
||||
roles: { type: [String], required: true,
|
||||
_comment: "" },
|
||||
tags: { type: [String],
|
||||
_comment: "" },
|
||||
//deactivated: { type: Boolean },
|
||||
//participating: { type: [String] },
|
||||
//host: { type: Boolean },
|
||||
bookmarks: { type: [String],
|
||||
_comment: "" },
|
||||
});
|
||||
model.Users = common.mongoose.model('users', userSchema);
|
||||
model.Users._list = [ "" ];
|
||||
},
|
||||
models: model,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
app.get ("/api/msg/search/:phrase", function (req, res) {
|
||||
Message.find ({$text: {$search: req.params.phrase}) .then (function (err, results){
|
||||
if (err) {
|
||||
console.log (err);
|
||||
res .status(404) .json (err);
|
||||
} else {
|
||||
console.log(JSON.stringify(results));
|
||||
res.json(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
*/
|
||||
module.exports = dbs;
|
106
server/ldap_ohm.js
Normal file
106
server/ldap_ohm.js
Normal file
@ -0,0 +1,106 @@
|
||||
// Original file created by Prof.Dr. Matthias Hopf
|
||||
|
||||
/*
|
||||
* Valdiate ohm logins with ldap service
|
||||
*/
|
||||
const ldap = require('ldapjs');
|
||||
const ldap_escape = require('ldap-escape');
|
||||
|
||||
|
||||
// TODO: Where do I get the URL from?? A: Is given.
|
||||
var ldap_client = ldap.createClient({
|
||||
//url: 'ldap://gso2.ads1.fh-nuernberg.de/',
|
||||
url: 'ldap://sso.cs.ohm-hochschule.de:389/',
|
||||
//url: 'ldaps://sso.cs.ohm-hochschule.de:636/',
|
||||
reconnect: true,
|
||||
// timeouts don't work reliably
|
||||
});
|
||||
|
||||
// TODO: Where do I get the 'bindpath' parameters info from? A: Is given.
|
||||
const ldap_config = {
|
||||
bindpath: 'cn=Users,dc=ohm-hochschule,dc=de',
|
||||
timeout: 2000
|
||||
};
|
||||
|
||||
const ldap_ohm = {
|
||||
init: function () {
|
||||
},
|
||||
|
||||
// Authorize user with password
|
||||
// Calls callback with null if unauthorized
|
||||
// Calls callback with object describing user if successful:
|
||||
authorize: function (user, pwd, cb) {
|
||||
if (typeof user != 'string' || typeof pwd != 'string')
|
||||
return cb (null);
|
||||
// Empty passwords *may* bind successfully anonymously
|
||||
if (user.length < 1 || pwd.length < 1)
|
||||
return cb (null);
|
||||
|
||||
/* Same function, different writing style */
|
||||
/* Escape ldap login input */
|
||||
//escaped = ldap_escape.dn`cn=${user},`+ldap_config.bindpath;
|
||||
escaped = ldap_escape.dn (['cn=',','+ldap_config.bindpath], user);
|
||||
|
||||
// Timeout handler: call callback,
|
||||
// make sure later ldap returns don't do anything weird
|
||||
var return_object = {};
|
||||
var timeoutHandle = setTimeout (function () {
|
||||
console.log('ldap timeout');
|
||||
return_object = null;
|
||||
cb (null);
|
||||
}, ldap_config.timeout);
|
||||
|
||||
// Bind ldap to user (authorize)
|
||||
ldap_client.bind (escaped, pwd, function (err, res) {
|
||||
if (return_object === null)
|
||||
return; // Timeout, cb has already been called
|
||||
if (err !== null) {
|
||||
console.log ("ldap bind: failed for user " + user + ": " + err);
|
||||
clearTimeout (timeoutHandle);
|
||||
return cb (null);
|
||||
}
|
||||
|
||||
// Search for user entry of just bound user
|
||||
// There should be only one...
|
||||
ldap_client.search (escaped, { sizeLimit: 1 }, function (err, res) {
|
||||
if (return_object === null)
|
||||
return; // Timeout, cb has already been called
|
||||
if (err !== null) {
|
||||
console.log ("ldap search: search after bind didn't work for user "
|
||||
+ user + ": " + err);
|
||||
clearTimeout (timeoutHandle);
|
||||
return cb (null);
|
||||
}
|
||||
// Populate return with search results
|
||||
res.on('searchEntry', function(entry) {
|
||||
if (return_object === null)
|
||||
return; // Timeout, cb has already been called
|
||||
return_object.user = user;
|
||||
return_object.name = entry.object.displayname;
|
||||
return_object.type = entry.object.employeetype;
|
||||
return_object.mail = entry.object.mail;
|
||||
return_object.gender = entry.object.orclgender;
|
||||
|
||||
// Calling cb here, not in 'end', because of potential bugs with
|
||||
// concurrency failures, and we have our single(!) entry
|
||||
// https://github.com/joyent/node-ldapjs/pull/424
|
||||
clearTimeout (timeoutHandle);
|
||||
if (typeof return_object.mail != 'string' || return_object.mail.length < 1) {
|
||||
console.log("ldap search error after bind for user " + user);
|
||||
return cb (null);
|
||||
}
|
||||
return cb (return_object);
|
||||
});
|
||||
res.on('error', function(err) {
|
||||
console.log('ldap error: ' + err.message);
|
||||
});
|
||||
res.on('end', function(result) {
|
||||
// TODO: Did we forget something?
|
||||
// TODO: analyze result.status?
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ldap_ohm;
|
35
server/ldap_test.js
Normal file
35
server/ldap_test.js
Normal file
@ -0,0 +1,35 @@
|
||||
// Terminal call: node server/ldap_test.js - needs VPN or eduroam
|
||||
const inquirer = require('inquirer'),
|
||||
ldap = require('./ldap_ohm.js');
|
||||
|
||||
inquirer.prompt([
|
||||
{
|
||||
name: 'username',
|
||||
type: 'input',
|
||||
message: 'Enter your VirtuOhm username:',
|
||||
validate: function( value ) {
|
||||
if (value.length) {
|
||||
return true;
|
||||
} else {
|
||||
return 'Please enter your username.';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'password',
|
||||
type: 'password',
|
||||
message: 'Enter your password:',
|
||||
validate: function(value) {
|
||||
if (value.length) {
|
||||
return true;
|
||||
} else {
|
||||
return 'Please enter your password.';
|
||||
}
|
||||
}
|
||||
}])
|
||||
.then(answers => {
|
||||
ldap.init(null);
|
||||
ldap.authorize(answers.username,answers.password,function(user) {
|
||||
console.log(JSON.stringify(user));
|
||||
});
|
||||
});
|
9
server_config.json
Normal file
9
server_config.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"dbConn": "mongodb://127.0.0.1:27017/om",
|
||||
"dbLocalConn": "mongodb://localhost:27017/omdb",
|
||||
"dbUser": "om",
|
||||
"dbPwd": "aeg1phuKeDaixese",
|
||||
"initialReservedTime": 120,
|
||||
"httpPort": 8013,
|
||||
"httpsPort": 8889
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
|
||||
const TagSchema = mongoose.Schema({
|
||||
name: { type: String, required: true }, //unique
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('Tag', TagSchema);
|
@ -1,14 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
|
||||
const UserSchema = mongoose.Schema({
|
||||
name: { type: String, required: true },
|
||||
password: {type: String}, password: {type: String},
|
||||
|
||||
role: {type: String, required: true},
|
||||
tags: [{type: String }],
|
||||
});
|
||||
//tags as index:
|
||||
//UserSchema.index({tags:'text'});
|
||||
|
||||
module.exports = mongoose.model('User', UserSchema);
|
Loading…
x
Reference in New Issue
Block a user