”2016-04-08”

This commit is contained in:
Martin Donnelly 2016-04-08 16:45:02 +01:00
parent bb2daacd2b
commit 4567ad83fd
39 changed files with 2307 additions and 21 deletions

View File

@ -0,0 +1,26 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
[*.{js,json,hbs,html,css}]
indent_style = space
indent_size = 2
[*.hbs]
insert_final_newline = false
[*.{diff,md}]
indent_size = 2
trim_trailing_whitespace = false

194
O-BrandServer/.gitignore vendored Normal file
View File

@ -0,0 +1,194 @@
### Archives template
# It's better to unpack these files and commit the raw source because
# git has its own built in compression methods.
*.7z
*.jar
*.rar
*.zip
*.gz
*.bzip
*.bz2
*.xz
*.lzma
*.cab
#packing-only formats
*.iso
*.tar
#package management formats
*.dmg
*.xpi
*.gem
*.egg
*.deb
*.rpm
*.msi
*.msm
*.msp
### Windows template
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
### OSX template
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Node template
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
# dependencies
/node_modules
/bower_components
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log
/.cache
/.gradle
/server/static/*
/wwwroot/assets

46
O-BrandServer/.jscsrc Normal file
View File

@ -0,0 +1,46 @@
{
"disallowKeywords": ["with"],
"disallowKeywordsOnNewLine": ["else"],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleVarDecl": "exceptUndefined",
"disallowNewlineBeforeBlockStatements": true,
"disallowQuotedKeysInObjects": true,
"disallowSpaceAfterObjectKeys": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpacesInFunction": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideParentheses": true,
"disallowTrailingWhitespace": true,
"maximumLineLength": 120,
"requireCamelCaseOrUpperCaseIdentifiers": false,
"requireCapitalizedComments": true,
"requireCapitalizedConstructors": true,
"requireCurlyBraces": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"case",
"return",
"try",
"catch",
"typeof"
],
"requireSpaceAfterLineComment": true,
"requireSpaceAfterBinaryOperators": true,
"requireSpaceBeforeBinaryOperators": true,
"requireSpaceBeforeBlockStatements": true,
"requireSpaceBeforeObjectValues": true,
"requireSpacesInFunction": {
"beforeOpeningCurlyBrace": true
},
"requireTrailingComma": false,
"requireEarlyReturn": true,
"validateIndentation": 2,
"validateLineBreaks": "LF",
"validateQuoteMarks": "'"
}

34
O-BrandServer/.jshintrc Normal file
View File

@ -0,0 +1,34 @@
{
"predef": [
"server",
"document",
"window",
"-Promise"
],
"node": true,
"browser": false,
"boss": true,
"curly": true,
"debug": false,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esnext": true,
"unused": true
}

1
O-BrandServer/.pgpass Normal file
View File

@ -0,0 +1 @@
localhost:5432:oBrand:obrand:obrand

74
O-BrandServer/dbconfig.js Normal file
View File

@ -0,0 +1,74 @@
/**
*
* User: Martin Donnelly
* Date: 2016-04-04
* Time: 14:46
*
*/
var db = require('./server/units/db-connector').dbConnection;
var dbAccount = require('./server/units/db-accounts')(db);
var exec = require('child_process').exec;
function addUsers() {
'use strict';
dbAccount.addNewAccount({
username: 'Martin ', password: 'MPReoa43', email: 'martind2000@gmail.com'
})
.then(function(data) {
console.log(data);
dbAccount.addNewAccount({
username: 'Default', password: 'password', email: 'm@g.com'
})
.then(function(data) {
console.log(data);
return 'DONE';
})
.catch(function(err) {
console.error(err);
return -1;
});
})
.catch(function(err) {
console.error(err);
return -1;
});
}
function prepare_db() {
exec('psql -Upostgres -d oBrand -h localhost -f ./obrand.sql', function(err) {
if (err !== null) {
console.log('exec error: ' + err);
return -1;
} else {
addUsers();
}
});
}
function createDB() {
'use strict';
exec('createdb -Upostgres -h localhost oBrand', function(err) {
if (err !== null) {
console.log('exec error: ' + err);
return -1;
} else {
prepare_db();
}
});
}
createDB();

12
O-BrandServer/dbrebuild.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
echo Database rebuilder...
SQLFILE="obrand.sql"
createdb oBrand
if [[ ! -f "$SQLFILE" ]]; then
wget https://dl.dropboxusercontent.com/u/233909/obrand/obrand.sql -O obrand.sql
fi
psql -f obrand.sql oBrand

View File

@ -0,0 +1,21 @@
{
/**
* Application configuration section
* http://pm2.keymetrics.io/docs/usage/application-declaration/
*/
apps : [
// First application
{
name : "Obrand Admin Server",
script : "obrand-server.js",
env: {
COMMON_VARIABLE: "true"
},
env_production : {
NODE_ENV: "production"
}
}
]
}

View File

@ -0,0 +1,45 @@
/**
*
* User: Martin Donnelly
* Date: 2016-03-31
* Time: 09:44
*
*/
var express = require('express'), path = require('path'), http = require('http');
var session = require('session');
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('!n87klqX39cB:7ayiRzEL5yRy5y938'));
/*app.use(session({
secret: 'G)+W&2W5C3V6gXJ.8mSD!l/-n3D]EV', resave: false,
saveUninitialized: false
}));*/
app.use('/export',express.static(path.join(__dirname,'server/static')));
app.use('/css',express.static(path.join(__dirname,'server/css')));
app.use('/',express.static(path.join(__dirname,'wwwroot')));
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')));
});

668
O-BrandServer/obrand.sql Normal file
View File

@ -0,0 +1,668 @@
-- Database: "oBrand"
DROP DATABASE "oBrand";
-- Role: obrand
DROP ROLE obrand;
CREATE ROLE obrand LOGIN
ENCRYPTED PASSWORD 'md51e16472d06fb312d14e3001f44e9460e'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
CREATE DATABASE "oBrand"
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'C'
LC_CTYPE = 'C'
CONNECTION LIMIT = -1;
GRANT ALL ON DATABASE "oBrand" TO postgres;
GRANT CONNECT ON DATABASE "oBrand" TO obrand;
REVOKE ALL ON DATABASE "oBrand" FROM public;
ALTER DEFAULT PRIVILEGES
GRANT INSERT, SELECT, UPDATE ON TABLES
TO public;
ALTER DEFAULT PRIVILEGES
GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
TO postgres;
--
ALTER TABLE "profile" DROP CONSTRAINT IF EXISTS "profile_fk0";
ALTER TABLE "profile" DROP CONSTRAINT IF EXISTS "profile_fk1";
ALTER TABLE "venue" DROP CONSTRAINT IF EXISTS "venue_fk0";
ALTER TABLE "billing" DROP CONSTRAINT IF EXISTS "billing_fk0";
DROP TABLE IF EXISTS "logins";
DROP TABLE IF EXISTS "profile";
DROP TABLE IF EXISTS "company";
DROP TABLE IF EXISTS "venue";
DROP TABLE IF EXISTS "billing";
DROP TABLE IF EXISTS "master_beacons";
DROP TABLE IF EXISTS "pages";
-- SEQUENCES
-- Sequence: public.billing_id_seq
-- DROP SEQUENCE public.billing_id_seq;
CREATE SEQUENCE public.billing_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER TABLE public.billing_id_seq
OWNER TO postgres;
-- Sequence: public.company_id_seq
-- DROP SEQUENCE public.company_id_seq;
CREATE SEQUENCE public.company_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 2
CACHE 1;
ALTER TABLE public.company_id_seq
OWNER TO postgres;
GRANT ALL ON SEQUENCE public.company_id_seq TO postgres;
GRANT SELECT, UPDATE ON SEQUENCE public.company_id_seq TO obrand;
-- Sequence: public.logins_id_seq
-- DROP SEQUENCE public.logins_id_seq;
CREATE SEQUENCE public.logins_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 4
CACHE 1;
ALTER TABLE public.logins_id_seq
OWNER TO postgres;
GRANT ALL ON SEQUENCE public.logins_id_seq TO postgres;
GRANT SELECT, UPDATE ON SEQUENCE public.logins_id_seq TO obrand;
-- Sequence: public.pages_id_seq
-- DROP SEQUENCE public.pages_id_seq;
CREATE SEQUENCE public.pages_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 35
CACHE 1;
ALTER TABLE public.pages_id_seq
OWNER TO postgres;
GRANT ALL ON SEQUENCE public.pages_id_seq TO postgres;
GRANT SELECT, UPDATE ON SEQUENCE public.pages_id_seq TO obrand;
-- Sequence: public.profile_id_seq
-- DROP SEQUENCE public.profile_id_seq;
CREATE SEQUENCE public.profile_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 2
CACHE 1;
ALTER TABLE public.profile_id_seq
OWNER TO postgres;
GRANT ALL ON SEQUENCE public.profile_id_seq TO postgres;
GRANT SELECT, UPDATE ON SEQUENCE public.profile_id_seq TO obrand;
-- Sequence: public.venue_id_seq
-- DROP SEQUENCE public.venue_id_seq;
CREATE SEQUENCE public.venue_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER TABLE public.venue_id_seq
OWNER TO postgres;
-- ----
-- Table: public.company
-- DROP TABLE public.company;
CREATE TABLE public.company
(
id integer NOT NULL DEFAULT nextval('company_id_seq'::regclass),
cid character varying(22) NOT NULL,
company_name character varying(100) NOT NULL,
address1 character varying(150) NOT NULL,
address2 character varying(150),
address3 character varying(150),
town character varying(150) NOT NULL,
county character varying(150),
postcode character varying(12) NOT NULL,
country integer,
pcontact character varying(20) NOT NULL,
ocontact character varying(20),
mobile character varying(20),
email character varying(150) NOT NULL,
CONSTRAINT company_pk PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.company
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.company TO public;
GRANT ALL ON TABLE public.company TO postgres;
-- Table: public.billing
-- DROP TABLE public.billing;
CREATE TABLE public.billing
(
id integer NOT NULL DEFAULT nextval('billing_id_seq'::regclass),
company_id integer NOT NULL,
CONSTRAINT billing_pk PRIMARY KEY (id),
CONSTRAINT billing_fk0 FOREIGN KEY (company_id)
REFERENCES public.company (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.billing
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.billing TO public;
GRANT ALL ON TABLE public.billing TO postgres;
-- Table: public.logins
-- DROP TABLE public.logins;
CREATE TABLE public.logins
(
id integer NOT NULL DEFAULT nextval('logins_id_seq'::regclass),
username character varying(100) NOT NULL,
email character varying(150) NOT NULL,
password_hash character varying(78) NOT NULL,
password_reset_token character varying(128),
uid character varying(22),
CONSTRAINT logins_pk PRIMARY KEY (id),
CONSTRAINT logins_email_key UNIQUE (email),
CONSTRAINT logins_password_reset_token_key UNIQUE (password_reset_token),
CONSTRAINT logins_uid_key UNIQUE (uid),
CONSTRAINT logins_username_key UNIQUE (username)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.logins
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.logins TO public;
GRANT ALL ON TABLE public.logins TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE, TRIGGER ON TABLE public.logins TO obrand;
-- Table: public.master_beacons
-- DROP TABLE public.master_beacons;
CREATE TABLE public.master_beacons
(
id bigint NOT NULL,
uid uuid NOT NULL,
CONSTRAINT master_beacons_pk PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.master_beacons
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.master_beacons TO public;
GRANT ALL ON TABLE public.master_beacons TO postgres;
-- Table: public.pages
-- DROP TABLE public.pages;
CREATE TABLE public.pages
(
id integer NOT NULL DEFAULT nextval('pages_id_seq'::regclass),
cid character varying(22),
vid character varying(22),
pid character varying(22),
content integer,
title character varying(100) NOT NULL,
data json NOT NULL,
CONSTRAINT pages_pk PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.pages
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.pages TO public;
GRANT ALL ON TABLE public.pages TO postgres;
-- Table: public.profile
-- DROP TABLE public.profile;
CREATE TABLE public.profile
(
id integer NOT NULL DEFAULT nextval('profile_id_seq'::regclass),
uid character varying(22) NOT NULL,
forename character varying(75) NOT NULL,
surname character varying(75) NOT NULL,
gender integer NOT NULL,
dob date NOT NULL,
bio text NOT NULL,
member_of character varying(22),
CONSTRAINT profile_pk PRIMARY KEY (id),
CONSTRAINT profile_fk0 FOREIGN KEY (uid)
REFERENCES public.logins (uid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.profile
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.profile TO public;
GRANT ALL ON TABLE public.profile TO postgres;
--
-- Table: public.venue
-- DROP TABLE public.venue;
CREATE TABLE public.venue
(
id integer NOT NULL DEFAULT nextval('venue_id_seq'::regclass),
venue_name character varying(100) NOT NULL,
address1 character varying(150) NOT NULL,
address2 character varying(150),
address3 character varying(150),
town character varying(150) NOT NULL,
county character varying(150),
postcode character varying(12) NOT NULL,
country integer,
pcontact character varying(20) NOT NULL,
ocontact character varying(20),
mobile character varying(20),
email character varying(150) NOT NULL,
company_id integer NOT NULL,
CONSTRAINT venue_pk PRIMARY KEY (id),
CONSTRAINT venue_fk0 FOREIGN KEY (company_id)
REFERENCES public.company (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.venue
OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT ON TABLE public.venue TO public;
GRANT ALL ON TABLE public.venue TO postgres;
--
--ALTER TABLE "profile" ADD CONSTRAINT "profile_fk0" FOREIGN KEY ("uid") REFERENCES "logins"("uid");
--ALTER TABLE "profile" ADD CONSTRAINT "profile_fk1" FOREIGN KEY ("member_of") REFERENCES "company"("cid");
--ALTER TABLE "venue" ADD CONSTRAINT "venue_fk0" FOREIGN KEY ("company_id") REFERENCES "company"("id");
--ALTER TABLE "billing" ADD CONSTRAINT "billing_fk0" FOREIGN KEY ("company_id") REFERENCES "company"("id");
grant connect on database "oBrand" to obrand;
GRANT SELECT, UPDATE, INSERT, DELETE, TRIGGER ON TABLE public.logins TO obrand;
grant select, update on logins_id_seq to obrand;
grant select, update on profile_id_seq to obrand;
grant select, update on company_id_seq to obrand;
grant select, update on pages_pk to obrand;
-- functions
-- Function: public.getaccountdetails(character varying)
-- DROP FUNCTION public.getaccountdetails(character varying);
CREATE OR REPLACE FUNCTION public.getaccountdetails(IN _uid character varying)
RETURNS TABLE(id integer, email character varying, uid character varying, forename character varying, surname character varying, member_of character varying) AS
$BODY$
BEGIN
RETURN QUERY
SELECT
logins.id,
logins.email,
logins.uid,
profile.forename,
profile.surname,
profile.member_of
FROM logins
LEFT JOIN profile ON profile.uid = logins.uid
WHERE logins.uid = _uid;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION public.getaccountdetails(character varying)
OWNER TO postgres;
--
-- Function: public.insert_user(character varying, character varying, character varying, character varying)
-- DROP FUNCTION public.insert_user(character varying, character varying, character varying, character varying);
CREATE OR REPLACE FUNCTION public.insert_user(
_username character varying,
_email character varying,
_passwordhash character varying,
_uid character varying)
RETURNS void AS
$BODY$
BEGIN
INSERT into logins(username, email, password_hash, uid) Values(_username,_email,_passwordHash,_uid);
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.insert_user(character varying, character varying, character varying, character varying)
OWNER TO postgres;
--
-- Function: public.makememberof(character varying, character varying)
-- DROP FUNCTION public.makememberof(character varying, character varying);
CREATE OR REPLACE FUNCTION public.makememberof(
_uid character varying,
_cid character varying)
RETURNS void AS
$BODY$
BEGIN
UPDATE profile SET member_of = _cid WHERE uid = _uid;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.makememberof(character varying, character varying)
OWNER TO postgres;
--
-- Function: public.upsert_company(character varying, character varying, character varying, character varying, character varying, character varying, character varying, character varying, integer, character varying, character varying, character varying, character varying)
-- DROP FUNCTION public.upsert_company(character varying, character varying, character varying, character varying, character varying, character varying, character varying, character varying, integer, character varying, character varying, character varying, character varying);
CREATE OR REPLACE FUNCTION public.upsert_company(
_cid character varying,
_company_name character varying,
_address1 character varying,
_address2 character varying,
_address3 character varying,
_town character varying,
_county character varying,
_postcode character varying,
_country integer,
_pcontact character varying,
_ocontact character varying,
_mobile character varying,
_email character varying)
RETURNS void AS
$BODY$
BEGIN
WITH upsert AS (UPDATE company
SET cid = _cid,
company_name = _company_name,
address1 = _address1,
address2 = _address2,
address3 = _address3,
town = _town,
county = _county,
postcode = _postcode,
country = _country,
pcontact = _pcontact,
ocontact = _ocontact,
mobile = _mobile,
email = _email
WHERE cid = _cid
RETURNING *)
INSERT INTO company (
cid,
company_name,
address1,
address2,
address3,
town,
county,
postcode,
country,
pcontact,
ocontact,
mobile,
email
) SELECT
_cid,
_company_name,
_address1,
_address2,
_address3,
_town,
_county,
_postcode,
_country,
_pcontact,
_ocontact,
_mobile,
_email
WHERE NOT EXISTS(SELECT *
FROM upsert);
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.upsert_company(character varying, character varying, character varying, character varying, character varying, character varying, character varying, character varying, integer, character varying, character varying, character varying, character varying)
OWNER TO postgres;
--
-- Function: public.upsert_page(character varying, character varying, character varying, integer, character varying, json)
-- DROP FUNCTION public.upsert_page(character varying, character varying, character varying, integer, character varying, json);
CREATE OR REPLACE FUNCTION public.upsert_page(
_cid character varying,
_vid character varying,
_pid character varying,
_content integer,
_title character varying,
_data json)
RETURNS void AS
$BODY$
BEGIN
WITH upsert AS (UPDATE pages
SET cid = _cid, vid = _vid, content = _content, title = _title, data = _data
WHERE pid = _pid
RETURNING *)
INSERT INTO pages (cid, vid, pid, content, title, data) SELECT
_cid,
_vid,
_pid,
_content,
_title,
_data
WHERE NOT EXISTS(SELECT *
FROM upsert);
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.upsert_page(character varying, character varying, character varying, integer, character varying, json)
OWNER TO postgres;
--
-- Function: public.upsert_profile(character varying, character varying, character varying, integer, date, text)
-- DROP FUNCTION public.upsert_profile(character varying, character varying, character varying, integer, date, text);
CREATE OR REPLACE FUNCTION public.upsert_profile(
_uid character varying,
_forename character varying,
_surname character varying,
_gender integer,
_dob date,
_bio text)
RETURNS void AS
$BODY$
BEGIN
WITH upsert AS (UPDATE profile
SET forename = _forename, surname = _surname, gender = _gender, dob = _dob, bio = _bio
WHERE uid = _uid
RETURNING *)
INSERT INTO profile (uid, forename, surname, gender, dob, bio) SELECT
_uid,
_forename,
_surname,
_gender,
_dob,
_bio
WHERE NOT EXISTS(SELECT *
FROM upsert);
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.upsert_profile(character varying, character varying, character varying, integer, date, text)
OWNER TO postgres;

View File

@ -0,0 +1,37 @@
{
"name": "obrand-admin-server",
"version": "1.0.0",
"description": "Obrand Administration backend server",
"main": "obrand-server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+http://gitlab.silvrtree.co.uk/martind2000/obrand-admin-server.git"
},
"author": "Martin Donnelly <martind2000@gmail.com>",
"license": "ISC",
"dependencies": {
"bcrypt": "^0.8.5",
"bcrypt-as-promised": "^1.1.0",
"body-parser": "^1.15.0",
"colors": "^1.1.2",
"cookie-parser": "^1.4.1",
"express": "^4.13.4",
"glob": "^7.0.3",
"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",
"pug": "^2.0.0-alpha3",
"uuid-pure": "^1.0.10"
},
"devDependencies": {
"log4js": "^0.6.33",
"session": "^0.1.0",
"util": "^0.10.3"
}
}

20
O-BrandServer/rebuild.sh Normal file
View File

@ -0,0 +1,20 @@
#!/bin/bash
NVM="$HOME/.nvm"
NVM_VERSION="5.7.0"
DEV="$HOME/dev"
LIVE="$HOME/live"
SWAP="/swapfile"
DBSETUP="obrand-admin-server/dbrebuild.sh"
PKG_MANAGER=$( command -v yum || command -v apt-get ) || echo "Neither yum nor apt-get found"
PKG_DEVICE=$(basename $PKG_MANAGER)
echo Copying...
cd $DEV/O-Brand/dist
cp -ra . $DEV/obrand-admin-server/wwwroot
cd $DEV/obrand-admin-server
rsync -uav --exclude .git $DEV/obrand-admin-server/ $LIVE

View File

@ -0,0 +1,33 @@
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
}
}
};
res.status(200).send(response);
})
.catch(function(err) {
console.error(err);
res.status(401).end();
});
}
});
app.use('/accounts', accountsRouter);
};

View File

@ -0,0 +1,44 @@
/**
*
* User: Martin Donnelly
* Date: 2016-04-05
* Time: 11:48
*
*/
/*jshint node:true*/
var db = require('../units/db-connector').dbConnection;
var dbPages = require('../units/db-pages')(db);
var logger = require('log4js').getLogger();
module.exports = function(app) {
var express = require('express');
var beaconRouter = express.Router();
beaconRouter.get('/', function(req, res) {
'use strict';
var beacon = {};
if (req.headers.hasOwnProperty('beacon')) {
beacon = JSON.parse(req.headers.beacon);
logger.debug(beacon);
}
logger.info('gettingLatestAddedPage');
dbPages.getLatestAddedPage()
.then((d) => {
res.redirect(301, d.fullpath);
}).catch((err)=> {
console.error(err);
res.status(401).end();
});
});
app.use('/beacon', require('body-parser').json());
app.use('/beacon', require('body-parser').text());
app.use('/beacon', require('body-parser').urlencoded());
app.use('/beacon', beaconRouter);
};

View File

@ -0,0 +1,60 @@
/*jshint node:true*/
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) {
'use strict';
var id = req.params.id;
dbCompany.sqlGetSimpleCompany(id)
.then(function(data) {
const response = {
data: {
type: 'company', id: id, attributes: $U.reDashObject(data)
}
};
res.status(200).send(response);
})
.catch(function(err) {
console.error(err);
res.status(401).end();
});
});
companiesRouter.patch('/:id', function(req, res) {
'use strict';
if (/Bearer .+/.test(req.headers.authorization)) {
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();
});
app.use('/api/companies', require('body-parser').json({type: 'application/vnd.api+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,57 @@
/*jshint node:true*/
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) => {
'use strict';
dbAccounts.makeMemberOf(uid, cid)
.catch(function(err) {
console.error(err);
});
});
newcompaniesRouter.get('/', function(req, res) {
res.send({
newcompanies: []
});
});
newcompaniesRouter.post('/', function(req, res) {
'use strict';
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();
});
}
});
app.use('/api/newcompanies', require('body-parser').json({type: 'application/vnd.api+json'}));
app.use('/api/newcompanies', newcompaniesRouter);
};

View File

@ -0,0 +1,124 @@
/*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('pug');
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 doRenderPage = (page) => {
var compiledhtml;
var _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);
};
var eventRenderPage = (page) => {
doRenderPage(page);
};
eventHandler.on('renderPage', eventRenderPage);
module.exports = function(app) {
var express = require('express');
var pagesRouter = express.Router();
pagesRouter.get('/', function(req, res) {
dbPages.getFullPageList()
.then(function(data) {
const response = {
data: data
};
res.status(200).send(response);
}).catch((err)=> {
console.error(err);
res.status(401).end();
});
});
pagesRouter.get('/list', function(req, res) {
dbPages.getPageList()
.then(function(data) {
res.render('pages', {data: data});
}).catch((err)=> {
console.error(err);
res.status(401).end();
});
});
pagesRouter.post('/', function(req, res) {
dbPages.addNewPage(req.body.data)
.then(function(data) {
let response = {
data: data
};
res.status(200).send(response);
eventHandler.emit('renderPage', data.attributes);
})
.catch((err)=> {
console.error(err);
res.status(401).end();
});
});
pagesRouter.patch('/', function(req, res) {
dbPages.addNewPage(req.body.data)
.then(function(data) {
let response = {
data: data
};
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
}
});
});
app.use('/api/pages',
require('body-parser').json({type: 'application/vnd.api+json'}));
app.use('/api/pages', pagesRouter);
};

View File

@ -0,0 +1,82 @@
/*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) {
console.error(e);
res.status(401).end();
});
}
});
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) {
console.error(err);
res.status(401).end();
});
});
profilesRouter.delete('/:id', function(req, res) {
res.status(204).end();
});
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);
};

View File

@ -0,0 +1,58 @@
/*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) {
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" }');
}
});
app.use('/token', require('body-parser').urlencoded());
app.use('/token', tokenRouter);
};

1
O-BrandServer/server/css/mui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
.textcenter {
text-align: center !important;
}
.centerblock {
display: block;
margin-left: auto;
margin-right: auto;
}
#image.img {
max-width: 300px;
max-height: 300px;
}

11
O-BrandServer/server/css/pure.min.css vendored Normal file

File diff suppressed because one or more lines are too long

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,202 @@
'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) {
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;
};

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);

View File

@ -0,0 +1,135 @@
'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.getLatestAddedPage = function() {
return new Promise(function(resolve, reject) {
db.oneOrNone(
"select 'export/' || pages.pid::text || '.html' as fullpath from pages order by id desc limit 1;")
.then((d) => {
return resolve(d);
})
.catch((err)=> {
return reject(err);
});
});
};
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)=> {
return reject(err);
});
});
};
module.getFullPageList = function() {
return new Promise(function(resolve, reject) {
db.any("select * from pages;")
.then((d) => {
let rArray = [];
for (var l = 0; l < d.length; l++) {
let attributeObj = $U.newObjectFrom(d[l],
['id', 'cid', 'vid', 'pid', 'content', 'title']);
attributeObj = $U.populateObject(d[l].data, attributeObj);
let newObj = {
"id": attributeObj.id,
"type": "page",
"attributes": attributeObj
};
rArray.push(newObj);
}
return resolve(rArray);
})
.catch((err)=> {
return reject(err);
});
});
};
module.sqlInsertPage = function(data) {
return new Promise(function(resolve, reject) {
db.func('upsert_page', data)
.then(()=> {
return resolve('ok');
})
.catch((err)=> {
return reject(err);
});
});
};
module.addNewPage = function(data) {
return new Promise((resolve, reject) => {
let _data, _jsonData;
_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)
];
this.sqlInsertPage(sqlData)
.then(function() {
data.attributes = _data;
return resolve(data);
})
.catch(function(err) {
return reject(err);
});
});
};
return module;
};

View File

@ -0,0 +1,37 @@
/**
*
* 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 = 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;

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

View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
<!-- Most restrictive policy: -->
<site-control permitted-cross-domain-policies="none"/>
<!-- Least restrictive policy: -->
<!--
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
-->
</cross-domain-policy>

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ObrandAdmin</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="/" />
<meta name="obrand-admin/config/environment" content="%7B%22modulePrefix%22%3A%22obrand-admin%22%2C%22environment%22%3A%22production%22%2C%22baseURL%22%3A%22/%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%7D%2C%22APP%22%3A%7B%22name%22%3A%22obrand-admin%22%2C%22version%22%3A%220.0.0+2ccbb358%22%7D%2C%22contentSecurityPolicy%22%3A%7B%22style-src%22%3A%22%27self%27%20%27unsafe-inline%27%22%2C%22img-src%22%3A%22%27self%27%20www.gravatar.com%22%7D%2C%22exportApplicationGlobal%22%3Afalse%7D" />
<link rel="stylesheet" href="assets/vendor-d41d8cd98f00b204e9800998ecf8427e.css" integrity="sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= sha512-z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==" >
<link rel="stylesheet" href="assets/obrand-admin-cc86a84a03ef9a818dab932882431295.css" integrity="sha256-q0qQ776qz62WobVOhawEpYd3kc0MPUzLs9e8hlDJYro= sha512-XNpe7gZxlGcs5EJJPz47dYyzP5Id2h+JGHVZd9vsfD/1r/scj21PeWqF0WA7iHww9fJTrV7SeMeOVI2EKeMG+g==" >
</head>
<body>
<script src="assets/vendor-8cc4e4a3c23abb17ea84c1e012239435.js" integrity="sha256-reT6vu+8EbiFTS5lPIx3A4rXDl4w9MICXWPzL1mzjn4= sha512-8JKfEk1Dpme3ohQQzqLP8myeot6a8c5p1Pt8f1Eey9X52XlzRBlxv42vXM2JEWRTds5gVsDC79QKr/w0420EVA==" ></script>
<script src="assets/obrand-admin-a24b5ee6227a0ec2cb7cd3f36c99cb9a.js" integrity="sha256-y/d03TqzXpQPLfGvnjj1cZdv2lB5c8veViae9Is5rzc= sha512-R+pY/6NlOl5RcNc+5a+ARPDXy4T+ZVrSRcJ9KbL3r3ZCN/Wdl/QoEaoQlTrAPtROIzRSNxR3+qnZo49say3BoQ==" ></script>
</body>
</html>

View File

@ -0,0 +1,3 @@
# http://www.robotstxt.org
User-agent: *
Disallow:

View File

@ -9,8 +9,6 @@ var fs = require('fs');
var eventHandler = new Events();
var util = require('util');
var templates = {
basic: {path: __dirname + '/jade/type0.jade', compiled: null}
};
@ -25,7 +23,7 @@ var doRenderPage = (page) => {
var htmlfile = exportPath + _page.pid + '.html';
if (templates.basic.compiled === null) {
templates.basic.compiled = jade.compileFile(templates.basic.path);
templates.basic.compiled = jade.compileFile(templates.basic.path, {});
}
compiledhtml = templates.basic.compiled(_page);

View File

@ -1,14 +1,5 @@
/*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);

View File

@ -184,7 +184,6 @@ module.exports = function(db) {
});
};
//MakeMemberOf(cid, uid)
module.makeMemberOf = function(cid, uid) {
return new Promise((resolve, reject) => {
this.sqlMakeMemberOf(cid, uid)

View File

@ -30,7 +30,6 @@ module.exports = function(db) {
};
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])

View File

@ -20,7 +20,7 @@ module.exports = function(db) {
return new Promise(function(resolve, reject) {
db.oneOrNone(
"select 'export/' || pages.pid::text || '.html' as fullpath from pages order by id desc limit 1;")
'select \'export/\' || pages.pid::text || \'.html\' as fullpath from pages order by id desc limit 1;')
.then((d) => {
return resolve(d);
})
@ -35,7 +35,7 @@ module.exports = function(db) {
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;")
'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);
})
@ -48,7 +48,7 @@ module.exports = function(db) {
module.getFullPageList = function() {
return new Promise(function(resolve, reject) {
db.any("select * from pages;")
db.any('select * from pages;')
.then((d) => {
let rArray = [];
for (var l = 0; l < d.length; l++) {
@ -57,9 +57,9 @@ module.exports = function(db) {
attributeObj = $U.populateObject(d[l].data, attributeObj);
let newObj = {
"id": attributeObj.id,
"type": "page",
"attributes": attributeObj
id: attributeObj.id,
type: 'page',
attributes: attributeObj
};
rArray.push(newObj);
}