Server up and running and serving all the previous mocked stuff.

Also now serving api/pages as a list page and viewer.
This commit is contained in:
Martin Donnelly 2016-03-31 14:24:21 +01:00
parent fdf6e8a18f
commit 40a8337ab3
26 changed files with 1213 additions and 2 deletions

1
.gitignore vendored
View File

@ -190,3 +190,4 @@ npm-debug.log
testem.log testem.log
/.cache /.cache
/.gradle /.gradle
/server/static/*

View File

@ -5,7 +5,8 @@
"window", "window",
"-Promise" "-Promise"
], ],
"browser": true, "node": true,
"browser": false,
"boss": true, "boss": true,
"curly": true, "curly": true,
"debug": false, "debug": false,

39
obrand-server.js Normal file
View File

@ -0,0 +1,39 @@
/**
*
* User: Martin Donnelly
* Date: 2016-03-31
* Time: 09:44
*
*/
var express = require('express'), path = require('path'), http = require('http');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var globSync = require('glob').sync;
var colors = require('colors/safe');
var app = express();
app.set('port', process.env.PORT || 8086);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.json({type: 'application/vnd.api+json'}));
app.use(cookieParser());
app.use('/export',express.static(path.join(__dirname,'server/static')));
app.use('/css',express.static(path.join(__dirname,'server/css')));
console.log(path.join(__dirname,'server/static'));
var backend = globSync('./server/app/**/*.js', { cwd: __dirname }).map(require);
backend.forEach(function(route) { route(app); });
app.listen(app.get('port'), function() {
'use strict';
console.log(colors.magenta('Obrand Server listening on ' + app.get('port')));
});

View File

@ -13,9 +13,24 @@
"author": "Martin Donnelly <martind2000@gmail.com>", "author": "Martin Donnelly <martind2000@gmail.com>",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"bcrypt": "^0.8.5",
"bcrypt-as-promised": "^1.1.0",
"body-parser": "^1.15.0", "body-parser": "^1.15.0",
"colors": "^1.1.2",
"cookie-parser": "^1.4.1", "cookie-parser": "^1.4.1",
"express": "^4.13.4", "express": "^4.13.4",
"morgan": "^1.7.0" "glob": "^7.0.3",
"jade": "^1.11.0",
"md-utils": "git+http://gitlab.silvrtree.co.uk/martind2000/md-utils.git",
"moment": "^2.12.0",
"morgan": "^1.7.0",
"node-validator": "git+http://gitlab.silvrtree.co.uk/martind2000/node-validator.git",
"oauth2-server": "^2.4.1",
"pg-promise": "^3.4.3",
"uuid-pure": "^1.0.10"
},
"devDependencies": {
"log4js": "^0.6.33",
"util": "^0.10.3"
} }
} }

4
server/.jshintrc Normal file
View File

@ -0,0 +1,4 @@
{
"node": true,
"esnext": true
}

35
server/app/accounts.js Normal file
View File

@ -0,0 +1,35 @@
'use strict';
var db = require('../units/db-connector').dbConnection;
var dbAccounts = require('../units/db-accounts')(db);
module.exports = function(app) {
var express = require('express');
var accountsRouter = express.Router();
accountsRouter.get('/:uid', function(req, res) {
if (/Bearer .+/.test(req.headers.authorization)) {
dbAccounts.sqlGetAccountDetails(req.params.uid)
.then(function(data) {
'use strict';
const response = {
data: {
type: 'accounts', id: data.uid, attributes: {
uid: data.uid, login: data.email, forename: data.forename,
surname: data.surname, memberof: data.member_of
}
}
};
console.log(response);
res.status(200).send(response);
})
.catch(function(err) {
console.error(err);
res.status(401).end();
});
}
});
app.use('/accounts', accountsRouter);
};

86
server/app/companies.js Normal file
View File

@ -0,0 +1,86 @@
/*jshint node:true*/
'use strict';
var db = require('../units/db-connector').dbConnection;
var dbCompany = require('../units/db-company')(db);
var $U = require('md-utils');
module.exports = function(app) {
var express = require('express');
var companiesRouter = express.Router();
companiesRouter.get('/:id', function(req, res) {
var id = req.params.id;
dbCompany.sqlGetSimpleCompany(id)
.then(function(data) {
const response = {
data: {
type: 'company', id: id, attributes: $U.reDashObject(data)
}
};
console.log(response);
res.status(200).send(response);
})
.catch(function(err) {
console.error(err);
res.status(401).end();
});
});
companiesRouter.post('/', function(req, res) {
res.status(201).end();
});
companiesRouter.get('/:id', function(req, res) {
res.send({
companies: {
id: req.params.id
}
});
});
companiesRouter.patch('/:id', function(req, res) {
if (/Bearer .+/.test(req.headers.authorization)) {
console.log('Patching: ' + req.params.id);
console.log(req.body.data);
var updateData = $U.unDashObject(req.body.data.attributes);
dbCompany.addNewCompany(updateData)
.then(function(d) {
let response = {
data: {
type: 'company', id: d.cid, attributes: d
}
};
res.status(200).send(response);
})
.catch(function(e) {
console.error(e);
res.status(401).end();
});
}
});
companiesRouter.delete('/:id', function(req, res) {
res.status(204).end();
});
// The POST and PUT call will not contain a request body
// because the body-parser is not included by default.
// To use req.body, run:
// Npm install --save-dev body-parser
app.use('/api/companies', require('body-parser').json({type: 'application/vnd.api+json'}));
// After installing, you need to `use` the body-parser for
// this mock uncommenting the following line:
//
//App.use('/api/companies', require('body-parser').json());
app.use('/api/companies', companiesRouter);
};

View File

@ -0,0 +1,32 @@
doctype html
html(lang="en")
head
meta(name='viewport', content='width=device-width, initial-scale=1.0')
link(rel='stylesheet', href='/css/pure.min.css')
link(rel='stylesheet', href='/css/obrand.css')
title= title
body
.pure-g
.pure-u-1
h1.textcenter= title
#image.pure-u-1
if image_url
img.centerblock(src=image_url)
#links.pure-u-1.pure-menu
ul.pure-menu-list
if link1_text
li.pure-menu-item
a.pure-menu-link.textcenter(href=link1_url)=link1_text
if link2_text
li.pure-menu-item
a.pure-menu-link.textcenter(href=link2_url)=link2_text
if link3_text
li.pure-menu-item
a.pure-menu-link.textcenter(href=link3_url)=link3_text
if link4_text
li.pure-menu-item
a.pure-menu-link.textcenter(href=link4_url)=link4_text

View File

@ -0,0 +1,83 @@
/*jshint node:true*/
'use strict';
var db = require('../units/db-connector').dbConnection;
var dbCompany = require('../units/db-company')(db);
var dbAccounts = require('../units/db-accounts')(db);
var $U = require('md-utils');
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();
module.exports = function(app) {
var express = require('express');
var newcompaniesRouter = express.Router();
eventEmitter.on('makeMemberOf', (uid, cid) => {
console.log('Make ' + uid + ' a member of ' + cid);
dbAccounts.makeMemberOf(uid, cid)
.catch(function(err) {
console.error(err);
});
});
newcompaniesRouter.get('/', function(req, res) {
res.send({
newcompanies: []
});
});
newcompaniesRouter.post('/', function(req, res) {
var updateData = $U.unDashObject(req.body.data.attributes);
if (/Bearer .+/.test(req.headers.authorization)) {
dbCompany.addNewCompany(updateData)
.then(function(d) {
updateData.cid = d.cid;
let response = {
data: {
type: 'newcompany', id: d.cid, attributes: updateData
}
};
eventEmitter.emit('makeMemberOf', updateData.uid, d.cid);
res.status(200).send(response);
})
.catch(function(e) {
console.error(e);
res.status(401).end();
});
}
});
newcompaniesRouter.get('/:id', function(req, res) {
res.send({
newcompanies: {
id: req.params.id
}
});
});
newcompaniesRouter.put('/:id', function(req, res) {
res.send({
newcompanies: {
id: req.params.id
}
});
});
newcompaniesRouter.delete('/:id', function(req, res) {
res.status(204).end();
});
// The POST and PUT call will not contain a request body
// because the body-parser is not included by default.
// To use req.body, run:
// Npm install --save-dev body-parser
app.use('/api/newcompanies', require('body-parser').json({type: 'application/vnd.api+json'}));
// After installing, you need to `use` the body-parser for
// this mock uncommenting the following line:
app.use('/api/newcompanies', newcompaniesRouter);
};

140
server/app/pages.js Normal file
View File

@ -0,0 +1,140 @@
/*jshint node:true*/
'use strict';
var db = require('../units/db-connector').dbConnection;
var dbPages = require('../units/db-pages')(db);
var $U = require('md-utils');
var Events = require('events');
var jade = require('jade');
var fs = require('fs');
var eventHandler = new Events();
var util = require('util');
var templates = {
basic: {path: __dirname + '/jade/type0.jade', compiled: null}
};
var exportPath = __dirname + '/../static/';
var eventRenderPage = (page) => {
console.log('+++ eventRenderPage');
doRenderPage(page);
};
var doRenderPage = (page) => {
console.log('+ doRenderPage');
var compiledhtml, _page = $U.unDashObject(page);
var htmlfile = exportPath + _page.pid + '.html';
if (templates.basic.compiled === null) {
templates.basic.compiled = jade.compileFile(templates.basic.path);
}
compiledhtml = templates.basic.compiled(_page);
fs.writeFileSync(htmlfile, compiledhtml);
console.log('- doRenderPage');
};
eventHandler.on('renderPage', eventRenderPage);
module.exports = function(app) {
var express = require('express');
var pagesRouter = express.Router();
pagesRouter.get('/', function(req, res) {
dbPages.getPageList()
.then(function(data) {
console.log(util.inspect(data));
res.render('pages', {data:data});
}).catch((err)=> {
console.error(err);
res.status(401).end();
});
});
pagesRouter.post('/', function(req, res) {
console.log(util.inspect(req.body.data));
dbPages.addNewPage(req.body.data)
.then(function(data) {
let response = {
data: data
};
console.log('Finalising...');
res.status(200).send(response);
eventHandler.emit('renderPage',data.attributes);
})
.catch((err)=> {
console.error(err);
res.status(401).end();
});
});
pagesRouter.patch('/', function(req, res) {
console.log(util.inspect(req.body.data));
dbPages.addNewPage(req.body.data)
.then(function(data) {
let response = {
data: data
};
console.log('Finalising...');
res.status(200).send(response);
eventHandler.emit('renderPage',data.attributes);
})
.catch((err)=> {
console.error(err);
res.status(401).end();
});
});
pagesRouter.get('/:id', function(req, res) {
res.send({
pages: {
id: req.params.id
}
});
});
pagesRouter.put('/:id', function(req, res) {
res.send({
pages: {
id: req.params.id
}
});
});
pagesRouter.delete('/:id', function(req, res) {
res.status(204).end();
});
// The POST and PUT call will not contain a request body
// because the body-parser is not included by default.
// To use req.body, run:
// Npm install --save-dev body-parser
app.use('/api/pages', require('body-parser').json({type: 'application/vnd.api+json'}));
// After installing, you need to `use` the body-parser for
// this mock uncommenting the following line:
//
//App.use('/api/pages', require('body-parser').json());
app.use('/api/pages', pagesRouter);
};

114
server/app/profiles.js Normal file
View File

@ -0,0 +1,114 @@
/*jshint node:true*/
'use strict';
var db = require('../units/db-connector').dbConnection;
var dbAccounts = require('../units/db-accounts')(db);
module.exports = function(app) {
var express = require('express');
var profilesRouter = express.Router();
var moment = require('moment');
profilesRouter.get('/:uid', function(req, res) {
if (/Bearer .+/.test(req.headers.authorization)) {
dbAccounts.sqlGetProfile(req.params.uid)
.then(function(data) {
let response = {data: {}};
if (data === null) {
// No record yet, return an empty one.
response.data = {
type: 'profile', id: req.params.uid, attributes: {
forename: '', surname: '', gender: 0, dob: '', bio: ''
}};
} else {
response.data = {
type: 'profile', id: data.uid, attributes: {
forename: data.forename,
surname: data.surname,
gender: data.gender,
dob: moment(data.dob).format('YYYY-MM-DD'),
bio: data.bio
}
};
}
res.status(200).send(response);
})
.catch(function(e) {
'use strict';
console.error(e);
res.status(401).end();
});
};
});
profilesRouter.post('/', function(req, res) {
res.status(201).end();
});
profilesRouter.get('/:id', function(req, res) {
res.send({
profiles: {
id: req.params.id
}
});
});
profilesRouter.put('/:id', function(req, res) {
res.send({
profiles: {
id: req.params.id
}
});
});
profilesRouter.patch('/:id', function(req, res) {
var data = req.body.data;
var attr = data.attributes;
var updateData = {
uid: data.id,
forename: attr.forename,
surname: attr.surname,
gender: attr.gender,
dob: attr.dob,
bio: attr.bio
};
dbAccounts.addInsertProfile(updateData)
.then(function() {
let response = {
data: {
type: 'profile', id: req.params.id, attributes: data.attributes
}
};
res.status(200).send(response);
})
.catch(function(err) {
'use strict';
console.error(err);
res.status(401).end();
});
});
profilesRouter.delete('/:id', function(req, res) {
res.status(204).end();
});
// The POST and PUT call will not contain a request body
// because the body-parser is not included by default.
// To use req.body, run:
// Npm install --save-dev body-parser
// After installing, you need to `use` the body-parser for
// this mock uncommenting the following line:
//
//App.use('/api/profiles', require('body-parser').json());
app.use('/api/profiles', require('body-parser').json());
app.use('/api/profiles',
require('body-parser').json({type: 'application/vnd.api+json'}));
app.use('/api/profiles', profilesRouter);
};

90
server/app/token.js Normal file
View File

@ -0,0 +1,90 @@
/*jshint node:true*/
'use strict';
var db = require('../units/db-connector').dbConnection;
var dbAccounts = require('../units/db-accounts')(db);
var logger = require('log4js').getLogger();
module.exports = function(app) {
var express = require('express');
var tokenRouter = express.Router();
tokenRouter.get('/', function(req, res) {
res.send({
token: []
});
});
tokenRouter.post('/', function(req, res) {
logger.debug('POST');
if (req.body.hasOwnProperty('grant_type')) {
if (req.body.grant_type === 'password') {
dbAccounts.findAccount({
email: req.body.username,
password: req.body.password
})
.then(function(d) {
let loginObj = {
access_token: 'secret token!',
account_id: d.uid,
username: d.username,
account: d.email
};
// Res.status(200).send('{ "access_token": "secret token!", "account_id": d.id }');
res.status(200).send(loginObj);
})
.catch(function(err) {
logger.error(err);
res.status(400).send(
'{ "error": "No account could be found with those details" }');
});
} else {
logger.error('A');
res.status(400).send(
'{ "error": "No account could be found with those details" }');
}
} else {
logger.error('B');
logger.warn(req.body.hasOwnProperty('grant_type'));
res.status(400).send(
'{ "error": "No account could be found with those details" }');
}
});
tokenRouter.get('/:id', function(req, res) {
res.send({
token: {
id: req.params.id
}
});
});
tokenRouter.put('/:id', function(req, res) {
res.send({
token: {
id: req.params.id
}
});
});
tokenRouter.delete('/:id', function(req, res) {
res.status(204).end();
});
// The POST and PUT call will not contain a request body
// because the body-parser is not included by default.
// To use req.body, run:
// Npm install --save-dev body-parser
// After installing, you need to `use` the body-parser for
// this mock uncommenting the following line:
//
//app.use('/token', require('body-parser').json());
// app.use('/token', require('body-parser').text());
app.use('/token', require('body-parser').urlencoded());
app.use('/token', tokenRouter);
};

1
server/css/mui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

9
server/css/obrand.css Normal file
View File

@ -0,0 +1,9 @@
.textcenter {
text-align: center !important;
}
.centerblock {
display: block;
margin-left: auto;
margin-right: auto;
}

11
server/css/pure.min.css vendored Normal file

File diff suppressed because one or more lines are too long

25
server/index.js Normal file
View File

@ -0,0 +1,25 @@
/*jshint node:true*/
// To use it create some files under `mocks/`
// e.g. `server/mocks/ember-hamsters.js`
//
// module.exports = function(app) {
// app.get('/ember-hamsters', function(req, res) {
// res.send('hello');
// });
// };
module.exports = function(app) {
var globSync = require('glob').sync;
var mocks = globSync('./mocks/**/*.js', { cwd: __dirname }).map(require);
var proxies = globSync('./proxies/**/*.js', { cwd: __dirname }).map(require);
// Log proxy requests
var morgan = require('morgan');
app.use(morgan('dev'));
mocks.forEach(function(route) { route(app); });
proxies.forEach(function(route) { route(app); });
};

View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css"><link rel="stylesheet" href="css/obrand.css"><title>A simple page</title></head><body><div class="pure-g"><div class="pure-u-1"><h1 class="textcenter">A simple page</h1></div><div id="image" class="pure-u-1"><img src="http://lorempixel.com/300/300" class="centerblock"></div><div id="links" class="pure-u-1 pure-menu"><ul class="pure-menu-list"><li class="pure-menu-item"><a href="http://www.google.com" class="pure-menu-link textcenter">Google</a></li><li class="pure-menu-item"><a href="http://www.lycos.com" class="pure-menu-link textcenter">Lycos</a></li><li class="pure-menu-item"></li><a href="http://www.excite.com" class="pure-menu-link textcenter">Excite</a><li class="pure-menu-item"></li><a href="http://altavista.digital.com" class="pure-menu-link textcenter">Altavista</a></ul></div></div></body></html>

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
<link rel="stylesheet" href="css/obrand.css">
<title>My page</title>
</head>
<body>
<div class="pure-g">
<div class="pure-u-1">
<h1 class="textcenter">My page</h1>
</div>
<div id="image" class="pure-u-1"><img src="http://lorempixel.com/300/300" class="centerblock">
</div>
<div id="links" class="pure-u-1 pure-menu">
<ul class="pure-menu-list">
<li class="pure-menu-item"> <a href="http://www.google.com" class="pure-menu-link textcenter">this is my link</a></li>
</ul>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><title>My page</title></head><body><h1>My page</h1><div id="image"><img src="http://lorempixel.com/300/300"></div><div id="links"><ul><li><a href="http://www.google.com">this is my link</a></li></ul></div></body></html>

10
server/static/hello.html Normal file
View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

204
server/units/db-accounts.js Normal file
View File

@ -0,0 +1,204 @@
'use strict';
var mdValidator = require('node-validator');
var mdErrors = require('./md-errors');
var bcrypt = require('bcrypt-as-promised');
var newId = require('uuid-pure').newId;
module.exports = function(db) {
var module = {};
module.connectPGP = function() {
return new Promise(function(resolve, reject) {
db.query('select $1::int as number', [1])
.then((data)=> {
resolve(data);
})
.catch((error)=> {
reject(error);
});
});
};
module.sqlInsertAccount = function(data) {
let _data = data;
_data.uid = newId();
return new Promise(function(resolve, reject) {
db.func('insert_user',
[_data.username, _data.email, _data.hash, _data.uid])
.then(()=> {
return resolve('ok');
})
.catch((err)=> {
return reject(err);
});
});
};
module.sqlGetAccount = function(email) {
return new Promise(function(resolve, reject) {
db.oneOrNone('select * from logins where email=$1;', [email])
.then(function(d) {
return resolve(d);
})
.catch((err)=> {
return reject(err);
});
});
};
module.sqlGetAccountDetails = function(uid) {
return new Promise(function(resolve, reject) {
db.one('select * from getAccountDetails($1);',[uid])
.then(function(d) {
console.log('+ sqlGetAccountDetails');
console.log(d);
return resolve(d);
})
.catch((err)=> {
return reject(err);
});
});
};
module.sqlUpsertProfile = function(data) {
var propArray = [
data.uid,
data.forename,
data.surname,
data.gender,
data.dob,
data.bio
];
return new Promise(function(resolve, reject) {
db.func('upsert_profile', propArray)
.then(()=> {
return resolve(true);
})
.catch((err)=> {
return reject(err);
});
});
};
module.sqlMakeMemberOf = function(cid, uid) {
var propArray = [cid,uid];
return new Promise(function(resolve, reject) {
db.func('makeMemberOf', propArray)
.then(()=> {
return resolve(true);
})
.catch((err)=> {
return reject(err);
});
});
};
module.sqlGetProfile = function(uid) {
return new Promise(function(resolve, reject) {
db.oneOrNone('select * from profile where uid=$1;', [uid])
.then(function(d) {
return resolve(d);
})
.catch((err)=> {
return reject(err);
});
});
};
module.addNewAccount = function(data) {
var self = this;
return new Promise((resolve, reject) => {
let _data = {};
_data.username = data.username.trim();
_data.password = data.password.trim();
_data.email = data.email.trim();
if (Object.keys(data).length === 3) {
if (_data.username.length === 0 || _data.password.length === 0 || _data.email.length === 0) {
return reject(mdErrors.error(1000));
}
if (mdValidator.Email(data.email) === false) {
return reject(mdErrors.error(1001));
} else {
// It should be possible to insert the user now.
bcrypt.hash(data.password,10).then((d) => {
_data.hash = d;
self.sqlInsertAccount(_data)
.then(()=> {
return resolve({reply: 'user added'});
})
.catch((err)=> {
return reject(err);
});
});
}
} else {
// Error - required details missing
return reject(mdErrors.error(1002));
}
});
};
module.findAccount = function(data) {
var _data = data;
return new Promise((resolve, reject) => {
this.sqlGetAccount(_data.email)
.then((row) => {
if (row === null) {
return reject(mdErrors.error(1004));
}
// Check password against hash held in db
// noinspection JSUnresolvedVariable
bcrypt.compare(_data.password, row.password_hash)
.then(function() {
let loginDetails = {
id: row.id,
username: row.username,
email: row.email,
uid: row.uid
};
return resolve(loginDetails);
})
// Failure, reject
.catch(function() {
return reject(mdErrors.error(1004));
});
})
.catch(function(err) {
return reject(err);
});
});
};
module.addInsertProfile = function(data) {
return new Promise((resolve, reject) => {
this.sqlUpsertProfile(data)
.then((d)=> {
return resolve(d);
})
.catch((err)=> {
return reject(err);
});
});
};
//makeMemberOf(cid, uid)
module.makeMemberOf = function(cid, uid) {
return new Promise((resolve, reject) => {
this.sqlMakeMemberOf(cid, uid)
.then((d)=> {
return resolve(d);
})
.catch((err)=> {
return reject(err);
});
});
};
return module;
};

115
server/units/db-company.js Normal file
View File

@ -0,0 +1,115 @@
/**
*
* User: Martin Donnelly
* Date: 2016-03-15
* Time: 14:04
*
*/
'use strict';
var $V = require('node-validator');
var mdErrors = require('./md-errors');
var newId = require('uuid-pure').newId;
var $U = require('md-utils');
module.exports = function(db) {
var module = {};
module.sqlInsertCompany = function(data) {
return new Promise(function(resolve, reject) {
db.proc('upsert_company',data)
.then(()=> {
console.log('+sqlInsertCompany OK');
return resolve('ok');
})
.catch((err)=> {
console.log('+sqlInsertCompany failed');
console.log(err);
return reject(err);
});
});
};
module.sqlGetSimpleCompany = function(id) {
return new Promise(function(resolve, reject) {
//db.oneOrNone('select *, company_name company-name from company where cid=$1;', [id])
db.oneOrNone('select company.* from company where cid=$1;', [id])
.then(function(d) {
console.log(d);
return resolve(d);
})
.catch((err)=> {
console.log(err);
return reject(err);
});
});
};
module.addNewCompany = function(data) {
return new Promise((resolve, reject) => {
let _data;
_data = $U.cloneTrim(data);
_data = $U.sanitiseObj(_data,
{company_name: true, address1: true, address2: true, address3: true,
town: false, county: false, pcontact: true, ocontact: true,mobile: true});
if (_data.hasOwnProperty('company_name') && (_data.company_name.length === 0)) {
return reject(mdErrors.error(1100));
}
if ([
_data.address1, _data.address2, _data.address3
].join('').trim().length === 0) {
return reject(mdErrors.error(1101));
}
if ([_data.town, _data.county].join('').trim().length === 0) {
return reject(mdErrors.error(1102));
}
var pcv = $V.checkPostCode(_data.postcode);
if (pcv === '') {
return reject(mdErrors.error(1103));
} else {
_data.postcode = pcv;
}
_data.pcontact = $V.validatePhone(_data.pcontact);
_data.ocontact = $V.validatePhone(_data.ocontact);
_data.mobile = $V.validatePhone(_data.mobile);
if ([
_data.pcontact, _data.ocontact, _data.mobile
].join('').trim().length === 0) {
return reject(mdErrors.error(1104));
}
if (_data.email.length === 0 || !$V.Email(_data.email)) {
return reject(mdErrors.error(1105));
}
if (typeof _data.cid === 'undefined' || _data.cid === null) {
_data.cid = newId();
}
const sqlData = [_data.cid, _data.company_name, _data.address1, _data.address2,
_data.address3, _data.town, _data.county, _data.postcode, _data.country, _data.pcontact,
_data.ocontact, _data.mobile, _data.email];
this.sqlInsertCompany(sqlData)
.then(function(d) {
console.log('Inserted');
console.log(d);
return resolve({cid: _data.cid});
})
.catch(function(err) {
console.log('Failed to insert');
return reject(err);
});
});
};
return module;
};

View File

@ -0,0 +1,21 @@
'uses strict';
/**
*
* User: Martin Donnelly
* Date: 2016-03-11
* Time: 10:22
*
*/
var pgp = require('pg-promise')();
var cn = {
host: 'localhost',
port: 5432,
database: 'oBrand',
user: 'obrand',
password: 'obrand'
};
exports.dbConnection = pgp(cn);

87
server/units/db-pages.js Normal file
View File

@ -0,0 +1,87 @@
'use strict';
var mdErrors = require('./md-errors');
var newId = require('uuid-pure').newId;
var $U = require('md-utils');
/**
*
* User: Martin Donnelly
* Date: 2016-03-24
* Time: 11:10
*
*/
module.exports = function(db) {
var module = {};
module.getPageList = function() {
return new Promise(function(resolve, reject) {
db.any("select pages.cid, pages.pid, pages.title, company.company_name, '/export/' || pages.pid::text || '.html' as fullpath from pages join company on company.cid = pages.cid;")
.then((d) => {
return resolve(d);
})
.catch((err)=> {
console.log('+getPageList failed');
console.log(err);
return reject(err);
});
});
};
module.sqlInsertPage = function(data) {
return new Promise(function(resolve, reject) {
db.func('upsert_page',data)
.then((d)=> {
console.log(d);
console.log('+sqlInsertPage OK');
return resolve('ok');
})
.catch((err)=> {
console.log('+sqlInsertPage failed');
console.log(err);
return reject(err);
});
});
};
module.addNewPage = function(data) {
return new Promise((resolve, reject) => {
let _data, _jsonData;
console.log(data);
_data = $U.cloneTrim(data.attributes);
if (typeof _data.pid === 'undefined' || _data.pid === null) {
_data.pid = newId();
}
_jsonData = $U.newObjectFrom(_data, ['title','image-url','link1-text','link1-url','link2-text','link2-url','link3-text','link3-url','link4-text','link4-url']);
const sqlData = [_data.cid, _data.vid, _data.pid, _data.content, _data.title, JSON.stringify(_jsonData)];
console.log(sqlData);
this.sqlInsertPage(sqlData)
.then(function(d) {
console.log('Inserted');
console.log(d);
data.attributes = _data;
return resolve(data);
})
.catch(function(err) {
console.log('Failed to insert');
return reject(err);
});
});
};
return module;
};

38
server/units/md-errors.js Normal file
View File

@ -0,0 +1,38 @@
/**
*
* User: Martin Donnelly
* Date: 2016-03-10
* Time: 11:31
*
*/
var logger = require('log4js').getLogger();
var MDERRORS = new function() {
'use strict';
var errors = {
1000: {name: 'Account error', title: 'Signup data missing'},
1001: {name: 'Account error', title: 'Email address is not in the correct format'},
1002: {name: 'Account error', title: 'Required details missing'},
1003: {name: 'Account error', title: 'Email does not exist in login table'},
1004: {name: 'Account error', title: 'Email address or password are incorrect'},
1100: {name: 'Company Error', title: 'Company name is missing'},
1101: {name: 'Company Error', title: 'Address details are missing'},
1102: {name: 'Company Error', title: 'Town/County details are missing'},
1103: {name: 'Company Error', title: 'Postcode is missing / incorrect'},
1104: {name: 'Company Error', title: 'Contact phone number is missing'},
1105: {name: 'Company Error', title: 'Email is missing / invalid'}
};
this.error = function(code) {
var estring = '';
estring = errors[code].name + ': ' + errors[code].title + '\nCode: ' + code + '\n';
logger.error(estring);
return ({code: code, name: errors[code].name, title: errors[code].title, string: estring});
};
}();
module.exports = MDERRORS;

25
views/pages.jade Normal file
View File

@ -0,0 +1,25 @@
doctype html
html(lang="en")
head
meta(name='viewport', content='width=device-width, initial-scale=1.0')
link(rel='stylesheet', href='/css/mui.min.css')
title Generated Page List
body
.mui-container
.mui-panel
.mui--text-headline.mui-text-accent Generated Page List
#list.mui-panel
table.mui-table.mui-table--bordered
thead
tr
th Company
th Page Title
each item in data
tr
td= item.company_name
td
a.mui-btn.mui-btn--flat.mui-btn--primary(href=item.fullpath, target='_blank')=item.title