diff --git a/O-BrandServer/.editorconfig b/O-BrandServer/.editorconfig new file mode 100644 index 0000000..62d7dde --- /dev/null +++ b/O-BrandServer/.editorconfig @@ -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 + diff --git a/O-BrandServer/.gitignore b/O-BrandServer/.gitignore new file mode 100644 index 0000000..0854e72 --- /dev/null +++ b/O-BrandServer/.gitignore @@ -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 diff --git a/O-BrandServer/.jscsrc b/O-BrandServer/.jscsrc new file mode 100644 index 0000000..acd4f65 --- /dev/null +++ b/O-BrandServer/.jscsrc @@ -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": "'" +} diff --git a/O-BrandServer/.jshintrc b/O-BrandServer/.jshintrc new file mode 100644 index 0000000..cfbe4a8 --- /dev/null +++ b/O-BrandServer/.jshintrc @@ -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 +} diff --git a/O-BrandServer/.pgpass b/O-BrandServer/.pgpass new file mode 100644 index 0000000..c0fd1f6 --- /dev/null +++ b/O-BrandServer/.pgpass @@ -0,0 +1 @@ +localhost:5432:oBrand:obrand:obrand \ No newline at end of file diff --git a/O-BrandServer/dbconfig.js b/O-BrandServer/dbconfig.js new file mode 100644 index 0000000..3051975 --- /dev/null +++ b/O-BrandServer/dbconfig.js @@ -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(); diff --git a/O-BrandServer/dbrebuild.sh b/O-BrandServer/dbrebuild.sh new file mode 100755 index 0000000..20fb94c --- /dev/null +++ b/O-BrandServer/dbrebuild.sh @@ -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 \ No newline at end of file diff --git a/O-BrandServer/ecosystem.json b/O-BrandServer/ecosystem.json new file mode 100644 index 0000000..a9374ae --- /dev/null +++ b/O-BrandServer/ecosystem.json @@ -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" + } + } + ] + +} diff --git a/O-BrandServer/obrand-server.js b/O-BrandServer/obrand-server.js new file mode 100644 index 0000000..cbf4d24 --- /dev/null +++ b/O-BrandServer/obrand-server.js @@ -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'))); +}); diff --git a/O-BrandServer/obrand.sql b/O-BrandServer/obrand.sql new file mode 100644 index 0000000..418eb58 --- /dev/null +++ b/O-BrandServer/obrand.sql @@ -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; diff --git a/O-BrandServer/package.json b/O-BrandServer/package.json new file mode 100644 index 0000000..19a0f77 --- /dev/null +++ b/O-BrandServer/package.json @@ -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 ", + "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" + } +} diff --git a/O-BrandServer/rebuild.sh b/O-BrandServer/rebuild.sh new file mode 100644 index 0000000..ec42243 --- /dev/null +++ b/O-BrandServer/rebuild.sh @@ -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 + diff --git a/O-BrandServer/server/app/accounts.js b/O-BrandServer/server/app/accounts.js new file mode 100644 index 0000000..5759689 --- /dev/null +++ b/O-BrandServer/server/app/accounts.js @@ -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); +}; + diff --git a/O-BrandServer/server/app/beacon.js b/O-BrandServer/server/app/beacon.js new file mode 100644 index 0000000..61c1d7d --- /dev/null +++ b/O-BrandServer/server/app/beacon.js @@ -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); +}; diff --git a/O-BrandServer/server/app/companies.js b/O-BrandServer/server/app/companies.js new file mode 100644 index 0000000..db0b2a3 --- /dev/null +++ b/O-BrandServer/server/app/companies.js @@ -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); +}; diff --git a/O-BrandServer/server/app/jade/type0.jade b/O-BrandServer/server/app/jade/type0.jade new file mode 100644 index 0000000..6e8e28e --- /dev/null +++ b/O-BrandServer/server/app/jade/type0.jade @@ -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 diff --git a/O-BrandServer/server/app/newcompanies.js b/O-BrandServer/server/app/newcompanies.js new file mode 100644 index 0000000..43bf5ef --- /dev/null +++ b/O-BrandServer/server/app/newcompanies.js @@ -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); +}; diff --git a/O-BrandServer/server/app/pages.js b/O-BrandServer/server/app/pages.js new file mode 100644 index 0000000..d970cf3 --- /dev/null +++ b/O-BrandServer/server/app/pages.js @@ -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); +}; diff --git a/O-BrandServer/server/app/profiles.js b/O-BrandServer/server/app/profiles.js new file mode 100644 index 0000000..474472b --- /dev/null +++ b/O-BrandServer/server/app/profiles.js @@ -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); +}; diff --git a/O-BrandServer/server/app/token.js b/O-BrandServer/server/app/token.js new file mode 100644 index 0000000..5388e95 --- /dev/null +++ b/O-BrandServer/server/app/token.js @@ -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); +}; diff --git a/O-BrandServer/server/css/mui.min.css b/O-BrandServer/server/css/mui.min.css new file mode 100644 index 0000000..2850f4f --- /dev/null +++ b/O-BrandServer/server/css/mui.min.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{box-sizing:border-box}:after,:before{box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:Arial,Verdana,Tahoma;font-size:14px;font-weight:400;line-height:1.429;color:rgba(0,0,0,.87);background-color:#FFF}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#2196F3;text-decoration:none}a:focus,a:hover{color:#1976D2;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}p{margin:0 0 10px}ol,ul{margin-top:0;margin-bottom:10px}figure{margin:0}img{vertical-align:middle}hr{margin-top:20px;margin-bottom:20px;border:0;height:1px;background-color:rgba(0,0,0,.12)}.mui-container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.mui-container:after,.mui-container:before{content:" ";display:table}.mui-container:after{clear:both}@media (min-width:544px){.mui-container{max-width:570px}}@media (min-width:768px){.mui-container{max-width:740px}}@media (min-width:992px){.mui-container{max-width:960px}}@media (min-width:1200px){.mui-container{max-width:1170px}}.mui-container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.mui-container-fluid:after,.mui-container-fluid:before{content:" ";display:table}.mui-container-fluid:after{clear:both}.mui-row{margin-left:-15px;margin-right:-15px}.mui-row:after,.mui-row:before{content:" ";display:table}.mui-row:after{clear:both}.mui-col-lg-1,.mui-col-lg-10,.mui-col-lg-11,.mui-col-lg-12,.mui-col-lg-2,.mui-col-lg-3,.mui-col-lg-4,.mui-col-lg-5,.mui-col-lg-6,.mui-col-lg-7,.mui-col-lg-8,.mui-col-lg-9,.mui-col-md-1,.mui-col-md-10,.mui-col-md-11,.mui-col-md-12,.mui-col-md-2,.mui-col-md-3,.mui-col-md-4,.mui-col-md-5,.mui-col-md-6,.mui-col-md-7,.mui-col-md-8,.mui-col-md-9,.mui-col-sm-1,.mui-col-sm-10,.mui-col-sm-11,.mui-col-sm-12,.mui-col-sm-2,.mui-col-sm-3,.mui-col-sm-4,.mui-col-sm-5,.mui-col-sm-6,.mui-col-sm-7,.mui-col-sm-8,.mui-col-sm-9,.mui-col-xs-1,.mui-col-xs-10,.mui-col-xs-11,.mui-col-xs-12,.mui-col-xs-2,.mui-col-xs-3,.mui-col-xs-4,.mui-col-xs-5,.mui-col-xs-6,.mui-col-xs-7,.mui-col-xs-8,.mui-col-xs-9{min-height:1px;padding-left:15px;padding-right:15px}.mui-col-xs-1,.mui-col-xs-10,.mui-col-xs-11,.mui-col-xs-12,.mui-col-xs-2,.mui-col-xs-3,.mui-col-xs-4,.mui-col-xs-5,.mui-col-xs-6,.mui-col-xs-7,.mui-col-xs-8,.mui-col-xs-9{float:left}.mui-col-xs-1{width:8.33333%}.mui-col-xs-2{width:16.66667%}.mui-col-xs-3{width:25%}.mui-col-xs-4{width:33.33333%}.mui-col-xs-5{width:41.66667%}.mui-col-xs-6{width:50%}.mui-col-xs-7{width:58.33333%}.mui-col-xs-8{width:66.66667%}.mui-col-xs-9{width:75%}.mui-col-xs-10{width:83.33333%}.mui-col-xs-11{width:91.66667%}.mui-col-xs-12{width:100%}.mui-col-xs-offset-0{margin-left:0}.mui-col-xs-offset-1{margin-left:8.33333%}.mui-col-xs-offset-2{margin-left:16.66667%}.mui-col-xs-offset-3{margin-left:25%}.mui-col-xs-offset-4{margin-left:33.33333%}.mui-col-xs-offset-5{margin-left:41.66667%}.mui-col-xs-offset-6{margin-left:50%}.mui-col-xs-offset-7{margin-left:58.33333%}.mui-col-xs-offset-8{margin-left:66.66667%}.mui-col-xs-offset-9{margin-left:75%}.mui-col-xs-offset-10{margin-left:83.33333%}.mui-col-xs-offset-11{margin-left:91.66667%}.mui-col-xs-offset-12{margin-left:100%}@media (min-width:544px){.mui-col-sm-1,.mui-col-sm-10,.mui-col-sm-11,.mui-col-sm-12,.mui-col-sm-2,.mui-col-sm-3,.mui-col-sm-4,.mui-col-sm-5,.mui-col-sm-6,.mui-col-sm-7,.mui-col-sm-8,.mui-col-sm-9{float:left}.mui-col-sm-1{width:8.33333%}.mui-col-sm-2{width:16.66667%}.mui-col-sm-3{width:25%}.mui-col-sm-4{width:33.33333%}.mui-col-sm-5{width:41.66667%}.mui-col-sm-6{width:50%}.mui-col-sm-7{width:58.33333%}.mui-col-sm-8{width:66.66667%}.mui-col-sm-9{width:75%}.mui-col-sm-10{width:83.33333%}.mui-col-sm-11{width:91.66667%}.mui-col-sm-12{width:100%}.mui-col-sm-offset-0{margin-left:0}.mui-col-sm-offset-1{margin-left:8.33333%}.mui-col-sm-offset-2{margin-left:16.66667%}.mui-col-sm-offset-3{margin-left:25%}.mui-col-sm-offset-4{margin-left:33.33333%}.mui-col-sm-offset-5{margin-left:41.66667%}.mui-col-sm-offset-6{margin-left:50%}.mui-col-sm-offset-7{margin-left:58.33333%}.mui-col-sm-offset-8{margin-left:66.66667%}.mui-col-sm-offset-9{margin-left:75%}.mui-col-sm-offset-10{margin-left:83.33333%}.mui-col-sm-offset-11{margin-left:91.66667%}.mui-col-sm-offset-12{margin-left:100%}}@media (min-width:768px){.mui-col-md-1,.mui-col-md-10,.mui-col-md-11,.mui-col-md-12,.mui-col-md-2,.mui-col-md-3,.mui-col-md-4,.mui-col-md-5,.mui-col-md-6,.mui-col-md-7,.mui-col-md-8,.mui-col-md-9{float:left}.mui-col-md-1{width:8.33333%}.mui-col-md-2{width:16.66667%}.mui-col-md-3{width:25%}.mui-col-md-4{width:33.33333%}.mui-col-md-5{width:41.66667%}.mui-col-md-6{width:50%}.mui-col-md-7{width:58.33333%}.mui-col-md-8{width:66.66667%}.mui-col-md-9{width:75%}.mui-col-md-10{width:83.33333%}.mui-col-md-11{width:91.66667%}.mui-col-md-12{width:100%}.mui-col-md-offset-0{margin-left:0}.mui-col-md-offset-1{margin-left:8.33333%}.mui-col-md-offset-2{margin-left:16.66667%}.mui-col-md-offset-3{margin-left:25%}.mui-col-md-offset-4{margin-left:33.33333%}.mui-col-md-offset-5{margin-left:41.66667%}.mui-col-md-offset-6{margin-left:50%}.mui-col-md-offset-7{margin-left:58.33333%}.mui-col-md-offset-8{margin-left:66.66667%}.mui-col-md-offset-9{margin-left:75%}.mui-col-md-offset-10{margin-left:83.33333%}.mui-col-md-offset-11{margin-left:91.66667%}.mui-col-md-offset-12{margin-left:100%}}@media (min-width:992px){.mui-col-lg-1,.mui-col-lg-10,.mui-col-lg-11,.mui-col-lg-12,.mui-col-lg-2,.mui-col-lg-3,.mui-col-lg-4,.mui-col-lg-5,.mui-col-lg-6,.mui-col-lg-7,.mui-col-lg-8,.mui-col-lg-9{float:left}.mui-col-lg-1{width:8.33333%}.mui-col-lg-2{width:16.66667%}.mui-col-lg-3{width:25%}.mui-col-lg-4{width:33.33333%}.mui-col-lg-5{width:41.66667%}.mui-col-lg-6{width:50%}.mui-col-lg-7{width:58.33333%}.mui-col-lg-8{width:66.66667%}.mui-col-lg-9{width:75%}.mui-col-lg-10{width:83.33333%}.mui-col-lg-11{width:91.66667%}.mui-col-lg-12{width:100%}.mui-col-lg-offset-0{margin-left:0}.mui-col-lg-offset-1{margin-left:8.33333%}.mui-col-lg-offset-2{margin-left:16.66667%}.mui-col-lg-offset-3{margin-left:25%}.mui-col-lg-offset-4{margin-left:33.33333%}.mui-col-lg-offset-5{margin-left:41.66667%}.mui-col-lg-offset-6{margin-left:50%}.mui-col-lg-offset-7{margin-left:58.33333%}.mui-col-lg-offset-8{margin-left:66.66667%}.mui-col-lg-offset-9{margin-left:75%}.mui-col-lg-offset-10{margin-left:83.33333%}.mui-col-lg-offset-11{margin-left:91.66667%}.mui-col-lg-offset-12{margin-left:100%}}@media (min-width:1200px){.mui-col-xl-1,.mui-col-xl-10,.mui-col-xl-11,.mui-col-xl-12,.mui-col-xl-2,.mui-col-xl-3,.mui-col-xl-4,.mui-col-xl-5,.mui-col-xl-6,.mui-col-xl-7,.mui-col-xl-8,.mui-col-xl-9{float:left}.mui-col-xl-1{width:8.33333%}.mui-col-xl-2{width:16.66667%}.mui-col-xl-3{width:25%}.mui-col-xl-4{width:33.33333%}.mui-col-xl-5{width:41.66667%}.mui-col-xl-6{width:50%}.mui-col-xl-7{width:58.33333%}.mui-col-xl-8{width:66.66667%}.mui-col-xl-9{width:75%}.mui-col-xl-10{width:83.33333%}.mui-col-xl-11{width:91.66667%}.mui-col-xl-12{width:100%}.mui-col-xl-offset-0{margin-left:0}.mui-col-xl-offset-1{margin-left:8.33333%}.mui-col-xl-offset-2{margin-left:16.66667%}.mui-col-xl-offset-3{margin-left:25%}.mui-col-xl-offset-4{margin-left:33.33333%}.mui-col-xl-offset-5{margin-left:41.66667%}.mui-col-xl-offset-6{margin-left:50%}.mui-col-xl-offset-7{margin-left:58.33333%}.mui-col-xl-offset-8{margin-left:66.66667%}.mui-col-xl-offset-9{margin-left:75%}.mui-col-xl-offset-10{margin-left:83.33333%}.mui-col-xl-offset-11{margin-left:91.66667%}.mui-col-xl-offset-12{margin-left:100%}}.mui--text-display4{font-weight:300;font-size:112px;line-height:112px}.mui--text-display3{font-weight:400;font-size:56px;line-height:56px}.mui--text-display2{font-weight:400;font-size:45px;line-height:48px}.mui--text-display1,h1{font-weight:400;font-size:34px;line-height:40px}.mui--text-headline,h2{font-weight:400;font-size:24px;line-height:32px}.mui--text-title,h3{font-weight:400;font-size:20px;line-height:28px}.mui--text-subhead,h4{font-weight:400;font-size:16px;line-height:24px}.mui--text-body2,h5{font-weight:500;font-size:14px;line-height:24px}.mui--text-body1{font-weight:400;font-size:14px;line-height:20px}.mui--text-caption{font-weight:400;font-size:12px;line-height:16px}.mui--text-menu{font-weight:500;font-size:13px;line-height:17px}.mui--text-button{font-weight:500;font-size:14px;line-height:18px;text-transform:uppercase}.mui-panel{padding:15px;margin-bottom:20px;border-radius:0;background-color:#FFF;box-shadow:0 2px 2px 0 rgba(0,0,0,.16),0 0 2px 0 rgba(0,0,0,.12)}.mui-panel:after,.mui-panel:before{content:" ";display:table}.mui-panel:after{clear:both}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.mui-panel{box-shadow:0 -1px 2px 0 rgba(0,0,0,.12),-1px 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.16),0 0 2px 0 rgba(0,0,0,.12)}}.mui-btn{-webkit-animation-duration:.1ms;animation-duration:.1ms;-webkit-animation-name:mui-node-inserted;animation-name:mui-node-inserted;font-weight:500;font-size:14px;line-height:18px;text-transform:uppercase;color:rgba(0,0,0,.87);background-color:#FFF;transition:all .2s ease-in-out;display:inline-block;height:36px;padding:0 26px;margin-top:6px;margin-bottom:6px;border:none;border-radius:2px;cursor:pointer;-ms-touch-action:manipulation;touch-action:manipulation;background-image:none;text-align:center;line-height:36px;vertical-align:middle;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:14px;letter-spacing:.03em;position:relative;overflow:hidden}.mui-btn:active,.mui-btn:focus,.mui-btn:hover{color:rgba(0,0,0,.87);background-color:#fff}.mui-btn[disabled]:active,.mui-btn[disabled]:focus,.mui-btn[disabled]:hover{color:rgba(0,0,0,.87);background-color:#FFF}.mui-btn.mui-btn--flat{color:rgba(0,0,0,.87);background-color:transparent}.mui-btn.mui-btn--flat:active,.mui-btn.mui-btn--flat:focus,.mui-btn.mui-btn--flat:hover{color:rgba(0,0,0,.87);background-color:#f2f2f2}.mui-btn.mui-btn--flat[disabled]:active,.mui-btn.mui-btn--flat[disabled]:focus,.mui-btn.mui-btn--flat[disabled]:hover{color:rgba(0,0,0,.87);background-color:transparent}.mui-btn:active,.mui-btn:focus,.mui-btn:hover{outline:0;text-decoration:none;color:rgba(0,0,0,.87)}.mui-btn:focus,.mui-btn:hover{box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 2px rgba(0,0,0,.2)}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.mui-btn:focus,.mui-btn:hover{box-shadow:0 -1px 2px rgba(0,0,0,.12),-1px 0 2px rgba(0,0,0,.12),0 0 2px rgba(0,0,0,.12),0 2px 2px rgba(0,0,0,.2)}}.mui-btn:active{box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.mui-btn:active{box-shadow:0 -1px 2px rgba(0,0,0,.12),-1px 0 2px rgba(0,0,0,.12),0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}}.mui-btn.mui--is-disabled,.mui-btn:disabled{cursor:not-allowed;pointer-events:none;opacity:.6;box-shadow:none}.mui-btn+.mui-btn{margin-left:8px}.mui-btn--flat{background-color:transparent}.mui-btn--flat:active,.mui-btn--flat:focus,.mui-btn--flat:hover{box-shadow:none;background-color:#f2f2f2}.mui-btn--fab,.mui-btn--raised{box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 2px rgba(0,0,0,.2)}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.mui-btn--fab,.mui-btn--raised{box-shadow:0 -1px 2px rgba(0,0,0,.12),-1px 0 2px rgba(0,0,0,.12),0 0 2px rgba(0,0,0,.12),0 2px 2px rgba(0,0,0,.2)}}.mui-btn--fab:active,.mui-btn--raised:active{box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.mui-btn--fab:active,.mui-btn--raised:active{box-shadow:0 -1px 2px rgba(0,0,0,.12),-1px 0 2px rgba(0,0,0,.12),0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}}.mui-btn--fab{position:relative;padding:0;width:55px;height:55px;line-height:55px;border-radius:50%;z-index:1}.mui-btn--primary{color:#FFF;background-color:#2196F3}.mui-btn--primary:active,.mui-btn--primary:focus,.mui-btn--primary:hover{color:#FFF;background-color:#39a1f4}.mui-btn--primary[disabled]:active,.mui-btn--primary[disabled]:focus,.mui-btn--primary[disabled]:hover{color:#FFF;background-color:#2196F3}.mui-btn--primary.mui-btn--flat{color:#2196F3;background-color:transparent}.mui-btn--primary.mui-btn--flat:active,.mui-btn--primary.mui-btn--flat:focus,.mui-btn--primary.mui-btn--flat:hover{color:#2196F3;background-color:#f2f2f2}.mui-btn--primary.mui-btn--flat[disabled]:active,.mui-btn--primary.mui-btn--flat[disabled]:focus,.mui-btn--primary.mui-btn--flat[disabled]:hover{color:#2196F3;background-color:transparent}.mui-btn--dark{color:#FFF;background-color:#424242}.mui-btn--dark:active,.mui-btn--dark:focus,.mui-btn--dark:hover{color:#FFF;background-color:#4f4f4f}.mui-btn--dark[disabled]:active,.mui-btn--dark[disabled]:focus,.mui-btn--dark[disabled]:hover{color:#FFF;background-color:#424242}.mui-btn--dark.mui-btn--flat{color:#424242;background-color:transparent}.mui-btn--dark.mui-btn--flat:active,.mui-btn--dark.mui-btn--flat:focus,.mui-btn--dark.mui-btn--flat:hover{color:#424242;background-color:#f2f2f2}.mui-btn--dark.mui-btn--flat[disabled]:active,.mui-btn--dark.mui-btn--flat[disabled]:focus,.mui-btn--dark.mui-btn--flat[disabled]:hover{color:#424242;background-color:transparent}.mui-btn--danger{color:#FFF;background-color:#F44336}.mui-btn--danger:active,.mui-btn--danger:focus,.mui-btn--danger:hover{color:#FFF;background-color:#f55a4e}.mui-btn--danger[disabled]:active,.mui-btn--danger[disabled]:focus,.mui-btn--danger[disabled]:hover{color:#FFF;background-color:#F44336}.mui-btn--danger.mui-btn--flat{color:#F44336;background-color:transparent}.mui-btn--danger.mui-btn--flat:active,.mui-btn--danger.mui-btn--flat:focus,.mui-btn--danger.mui-btn--flat:hover{color:#F44336;background-color:#f2f2f2}.mui-btn--danger.mui-btn--flat[disabled]:active,.mui-btn--danger.mui-btn--flat[disabled]:focus,.mui-btn--danger.mui-btn--flat[disabled]:hover{color:#F44336;background-color:transparent}.mui-btn--accent{color:#FFF;background-color:#FF4081}.mui-btn--accent:active,.mui-btn--accent:focus,.mui-btn--accent:hover{color:#FFF;background-color:#ff5a92}.mui-btn--accent[disabled]:active,.mui-btn--accent[disabled]:focus,.mui-btn--accent[disabled]:hover{color:#FFF;background-color:#FF4081}.mui-btn--accent.mui-btn--flat{color:#FF4081;background-color:transparent}.mui-btn--accent.mui-btn--flat:active,.mui-btn--accent.mui-btn--flat:focus,.mui-btn--accent.mui-btn--flat:hover{color:#FF4081;background-color:#f2f2f2}.mui-btn--accent.mui-btn--flat[disabled]:active,.mui-btn--accent.mui-btn--flat[disabled]:focus,.mui-btn--accent.mui-btn--flat[disabled]:hover{color:#FF4081;background-color:transparent}.mui-btn--small{height:30.6px;line-height:30.6px;padding:0 16px;font-size:13px}.mui-btn--large{height:54px;line-height:54px;padding:0 26px;font-size:14px}.mui-btn--fab.mui-btn--small{width:44px;height:44px;line-height:44px}.mui-btn--fab.mui-btn--large{width:75px;height:75px;line-height:75px}.mui-ripple-effect{position:absolute;border-radius:50%;pointer-events:none;opacity:0;-webkit-animation:mui-ripple-animation 2s;animation:mui-ripple-animation 2s}@-webkit-keyframes mui-ripple-animation{from{-webkit-transform:scale(1);transform:scale(1);opacity:.4}to{-webkit-transform:scale(100);transform:scale(100);opacity:0}}@keyframes mui-ripple-animation{from{-webkit-transform:scale(1);transform:scale(1);opacity:.4}to{-webkit-transform:scale(100);transform:scale(100);opacity:0}}.mui-btn>.mui-ripple-effect{background-color:#a6a6a6}.mui-btn--primary>.mui-ripple-effect{background-color:#FFF}.mui-btn--dark>.mui-ripple-effect{background-color:#FFF}.mui-btn--danger>.mui-ripple-effect{background-color:#FFF}.mui-btn--accent>.mui-ripple-effect{background-color:#FFF}.mui-btn--flat>.mui-ripple-effect{background-color:#a6a6a6}.mui--appbar-height{height:56px}.mui--appbar-min-height,.mui-appbar{min-height:56px}.mui--appbar-line-height{line-height:56px}.mui--appbar-top{top:56px}@media (orientation:landscape) and (max-height:480px){.mui--appbar-height{height:48px}.mui--appbar-min-height,.mui-appbar{min-height:48px}.mui--appbar-line-height{line-height:48px}.mui--appbar-top{top:48px}}@media (min-width:480px){.mui--appbar-height{height:64px}.mui--appbar-min-height,.mui-appbar{min-height:64px}.mui--appbar-line-height{line-height:64px}.mui--appbar-top{top:64px}}.mui-appbar{background-color:#2196F3;color:#FFF}strong{font-weight:700}abbr[title]{cursor:help;border-bottom:1px dotted #2196F3}h1,h2,h3{margin-top:20px;margin-bottom:10px}h4,h5,h6{margin-top:10px;margin-bottom:10px}.mui-divider{display:block;height:1px;background-color:rgba(0,0,0,.12)}.mui--divider-top{border-top:1px solid rgba(0,0,0,.12)}.mui--divider-bottom{border-bottom:1px solid rgba(0,0,0,.12)}.mui--divider-left{border-left:1px solid rgba(0,0,0,.12)}.mui--divider-right{border-right:1px solid rgba(0,0,0,.12)}legend{display:block;width:100%;padding:0;margin-bottom:10px;font-size:21px;color:rgba(0,0,0,.87);line-height:inherit;border:0}input[type=search]{box-sizing:border-box;-webkit-appearance:none}input[type=checkbox]:focus,input[type=radio]:focus,input[type=file]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}.mui-textfield{display:block;padding-top:15px;margin-bottom:20px;position:relative}.mui-textfield>label{position:absolute;top:0;display:block;width:100%;color:rgba(0,0,0,.54);font-size:12px;font-weight:400;line-height:15px;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.mui-textfield>textarea{padding-top:5px}.mui-textfield>input,.mui-textfield>textarea{display:block}.mui-textfield>input:focus~label,.mui-textfield>textarea:focus~label{color:#2196F3}.mui-textfield--float-label>label{position:absolute;-webkit-transform:translate(0,15px);transform:translate(0,15px);font-size:16px;line-height:32px;color:rgba(0,0,0,.26);text-overflow:clip;cursor:text;pointer-events:none}.mui-textfield--float-label>input:focus~label,.mui-textfield--float-label>textarea:focus~label{-webkit-transform:translate(0,0);transform:translate(0,0);font-size:12px;line-height:15px;text-overflow:ellipsis}.mui-textfield--float-label>input:not(:focus).mui--is-not-empty~label,.mui-textfield--float-label>input:not(:focus):not(:empty):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield--float-label>input:not(:focus)[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield--float-label>textarea:not(:focus).mui--is-not-empty~label,.mui-textfield--float-label>textarea:not(:focus):not(:empty):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield--float-label>textarea:not(:focus)[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty)~label{color:rgba(0,0,0,.54);font-size:12px;line-height:15px;-webkit-transform:translate(0,0);transform:translate(0,0);text-overflow:ellipsis}.mui-textfield--wrap-label{display:table;width:100%;padding-top:0}.mui-textfield--wrap-label:not(.mui-textfield--float-label)>label{display:table-header-group;position:static;white-space:normal;overflow-x:visible}.mui-textfield>input,.mui-textfield>textarea{-webkit-animation-duration:.1ms;animation-duration:.1ms;-webkit-animation-name:mui-node-inserted;animation-name:mui-node-inserted;display:block;background-color:transparent;color:rgba(0,0,0,.87);border:none;border-bottom:1px solid rgba(0,0,0,.26);outline:0;width:100%;font-size:16px;padding:0;box-shadow:none;border-radius:0;background-image:none}.mui-textfield>input:focus,.mui-textfield>textarea:focus{border-color:#2196F3;border-width:2px}.mui-textfield>input:-moz-read-only,.mui-textfield>input:disabled,.mui-textfield>textarea:-moz-read-only,.mui-textfield>textarea:disabled{cursor:not-allowed;background-color:transparent;opacity:1}.mui-textfield>input:disabled,.mui-textfield>input:read-only,.mui-textfield>textarea:disabled,.mui-textfield>textarea:read-only{cursor:not-allowed;background-color:transparent;opacity:1}.mui-textfield>input::-webkit-input-placeholder,.mui-textfield>textarea::-webkit-input-placeholder{color:rgba(0,0,0,.26);opacity:1}.mui-textfield>input::-moz-placeholder,.mui-textfield>textarea::-moz-placeholder{color:rgba(0,0,0,.26);opacity:1}.mui-textfield>input:-ms-input-placeholder,.mui-textfield>textarea:-ms-input-placeholder{color:rgba(0,0,0,.26);opacity:1}.mui-textfield>input::placeholder,.mui-textfield>textarea::placeholder{color:rgba(0,0,0,.26);opacity:1}.mui-textfield>input{height:32px}.mui-textfield>input:focus{height:33px;margin-bottom:-1px}.mui-textfield>textarea{min-height:64px}.mui-textfield>textarea[rows]:not([rows="2"]):focus{margin-bottom:-1px}.mui-textfield>input:focus{height:33px;margin-bottom:-1px}.mui-checkbox,.mui-radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.mui-checkbox>label,.mui-radio>label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.mui-checkbox--inline>label>input[type=checkbox],.mui-checkbox>label>input[type=checkbox],.mui-radio--inline>label>input[type=radio],.mui-radio>label>input[type=radio]{position:absolute;margin-left:-20px;margin-top:4px}.mui-checkbox+.mui-checkbox,.mui-radio+.mui-radio{margin-top:-5px}.mui-checkbox--inline,.mui-radio--inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.mui-checkbox--inline>input[type=checkbox],.mui-checkbox--inline>input[type=radio],.mui-checkbox--inline>label>input[type=checkbox],.mui-checkbox--inline>label>input[type=radio],.mui-radio--inline>input[type=checkbox],.mui-radio--inline>input[type=radio],.mui-radio--inline>label>input[type=checkbox],.mui-radio--inline>label>input[type=radio]{margin:4px 0 0;line-height:normal}.mui-checkbox--inline+.mui-checkbox--inline,.mui-radio--inline+.mui-radio--inline{margin-top:0;margin-left:10px}.mui-select{display:block;padding-top:15px;margin-bottom:20px;position:relative}.mui-select:focus{outline:0}.mui-select:focus>select{height:33px;margin-bottom:-1px;border-color:#2196F3;border-width:2px}.mui-select>select{-webkit-animation-duration:.1ms;animation-duration:.1ms;-webkit-animation-name:mui-node-inserted;animation-name:mui-node-inserted;display:block;height:32px;width:100%;appearance:none;-webkit-appearance:none;-moz-appearance:none;outline:0;border:none;border-bottom:1px solid rgba(0,0,0,.26);border-radius:0;box-shadow:none;background-color:transparent;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNiIgd2lkdGg9IjEwIj48cG9seWdvbiBwb2ludHM9IjAsMCAxMCwwIDUsNiIgc3R5bGU9ImZpbGw6cmdiYSgwLDAsMCwuMjQpOyIvPjwvc3ZnPg==);background-repeat:no-repeat;background-position:right center;cursor:pointer;color:rgba(0,0,0,.87);font-size:16px;padding:0 25px 0 0}.mui-select>select::-ms-expand{display:none}.mui-select>select:focus{outline:0;height:33px;margin-bottom:-1px;border-color:#2196F3;border-width:2px}.mui-select>select:disabled{color:rgba(0,0,0,.38);cursor:not-allowed;background-color:transparent;opacity:1}.mui-select__menu{position:absolute;z-index:1;min-width:100%;overflow-y:auto;padding:8px 0;background-color:#FFF;font-size:16px}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.mui-select__menu{border-left:1px solid rgba(0,0,0,.12);border-top:1px solid rgba(0,0,0,.12)}}.mui-select__menu>div{padding:0 22px;height:42px;line-height:42px;cursor:pointer;white-space:nowrap}.mui-select__menu>div:hover{background-color:#E0E0E0}.mui-select__menu>div.mui--is-selected{background-color:#EEE}@media (min-width:544px){.mui-form--inline>.mui-textfield{display:inline-block;margin-bottom:0}.mui-form--inline>.mui-checkbox,.mui-form--inline>.mui-radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.mui-form--inline>.mui-checkbox>label,.mui-form--inline>.mui-radio>label{padding-left:0}.mui-form--inline>.mui-checkbox>label>input[type=checkbox],.mui-form--inline>.mui-radio>label>input[type=radio]{position:relative;margin-left:0}.mui-form--inline>.mui-select{display:inline-block}.mui-form--inline>.mui-btn{margin-bottom:0;margin-top:0;vertical-align:bottom}}.mui-textfield>input:invalid:not(:focus):not(:required),.mui-textfield>input:invalid:not(:focus):required.mui--is-empty.mui--is-dirty,.mui-textfield>input:invalid:not(:focus):required.mui--is-not-empty,.mui-textfield>input:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>input:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>input:not(:focus).mui--is-invalid:not(:required),.mui-textfield>input:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty,.mui-textfield>input:not(:focus).mui--is-invalid:required.mui--is-not-empty,.mui-textfield>input:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>input:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>textarea:invalid:not(:focus):not(:required),.mui-textfield>textarea:invalid:not(:focus):required.mui--is-empty.mui--is-dirty,.mui-textfield>textarea:invalid:not(:focus):required.mui--is-not-empty,.mui-textfield>textarea:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>textarea:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>textarea:not(:focus).mui--is-invalid:not(:required),.mui-textfield>textarea:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty,.mui-textfield>textarea:not(:focus).mui--is-invalid:required.mui--is-not-empty,.mui-textfield>textarea:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>textarea:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty){border-color:#F44336;border-width:2px}.mui-textfield>input:invalid:not(:focus):not(:required),.mui-textfield>input:invalid:not(:focus):required.mui--is-empty.mui--is-dirty,.mui-textfield>input:invalid:not(:focus):required.mui--is-not-empty,.mui-textfield>input:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>input:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>input:not(:focus).mui--is-invalid:not(:required),.mui-textfield>input:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty,.mui-textfield>input:not(:focus).mui--is-invalid:required.mui--is-not-empty,.mui-textfield>input:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty),.mui-textfield>input:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty){height:33px;margin-bottom:-1px}.mui-textfield>input:invalid:not(:focus):not(:required)~label,.mui-textfield>input:invalid:not(:focus):required.mui--is-not-empty~label,.mui-textfield>input:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>input:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>input:not(:focus).mui--is-invalid:not(:required)~label,.mui-textfield>input:not(:focus).mui--is-invalid:required.mui--is-not-empty~label,.mui-textfield>input:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>input:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>textarea:invalid:not(:focus):not(:required)~label,.mui-textfield>textarea:invalid:not(:focus):required.mui--is-not-empty~label,.mui-textfield>textarea:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>textarea:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>textarea:not(:focus).mui--is-invalid:not(:required)~label,.mui-textfield>textarea:not(:focus).mui--is-invalid:required.mui--is-not-empty~label,.mui-textfield>textarea:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty)~label,.mui-textfield>textarea:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty)~label{color:#F44336}.mui-textfield:not(.mui-textfield--float-label)>input:invalid:not(:focus):required.mui--is-empty.mui--is-dirty~label,.mui-textfield:not(.mui-textfield--float-label)>input:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty~label,.mui-textfield:not(.mui-textfield--float-label)>textarea:invalid:not(:focus):required.mui--is-empty.mui--is-dirty~label,.mui-textfield:not(.mui-textfield--float-label)>textarea:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty~label{color:#F44336}th{text-align:left}.mui-table{width:100%;max-width:100%;margin-bottom:20px}.mui-table>tbody>tr>td,.mui-table>tbody>tr>th,.mui-table>tfoot>tr>td,.mui-table>tfoot>tr>th,.mui-table>thead>tr>td,.mui-table>thead>tr>th{padding:10px;line-height:1.429}.mui-table>thead>tr>th{border-bottom:2px solid rgba(0,0,0,.12);font-weight:700}.mui-table>tbody+tbody{border-top:2px solid rgba(0,0,0,.12)}.mui-table.mui-table--bordered>tbody>tr>td{border-bottom:1px solid rgba(0,0,0,.12)}.mui-dropdown{display:inline-block;position:relative}[data-mui-toggle=dropdown]{-webkit-animation-duration:.1ms;animation-duration:.1ms;-webkit-animation-name:mui-node-inserted;animation-name:mui-node-inserted;outline:0}.mui-dropdown__menu{position:absolute;top:100%;left:0;display:none;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#FFF;border-radius:2px;z-index:1;background-clip:padding-box}.mui-dropdown__menu.mui--is-open{display:block}.mui-dropdown__menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.429;color:rgba(0,0,0,.87);white-space:nowrap}.mui-dropdown__menu>li>a:focus,.mui-dropdown__menu>li>a:hover{text-decoration:none;color:rgba(0,0,0,.87);background-color:#EEE}.mui-dropdown__menu>.mui--is-disabled>a,.mui-dropdown__menu>.mui--is-disabled>a:focus,.mui-dropdown__menu>.mui--is-disabled>a:hover{color:#EEE}.mui-dropdown__menu>.mui--is-disabled>a:focus,.mui-dropdown__menu>.mui--is-disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;cursor:not-allowed}.mui-dropdown__menu--right{left:auto;right:0}.mui-tabs__bar{list-style:none;padding-left:0;margin-bottom:0;background-color:transparent;white-space:nowrap;overflow-x:auto}.mui-tabs__bar>li{display:inline-block}.mui-tabs__bar>li>a{display:block;white-space:nowrap;text-transform:uppercase;font-weight:500;font-size:14px;color:rgba(0,0,0,.87);cursor:default;height:48px;line-height:48px;padding-left:24px;padding-right:24px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mui-tabs__bar>li>a:hover{text-decoration:none}.mui-tabs__bar>li.mui--is-active{border-bottom:2px solid #2196F3}.mui-tabs__bar>li.mui--is-active>a{color:#2196F3}.mui-tabs__bar.mui-tabs__bar--justified{display:table;width:100%;table-layout:fixed}.mui-tabs__bar.mui-tabs__bar--justified>li{display:table-cell}.mui-tabs__bar.mui-tabs__bar--justified>li>a{text-align:center;padding-left:0;padding-right:0}.mui-tabs__pane{display:none}.mui-tabs__pane.mui--is-active{display:block}[data-mui-toggle=tab]{-webkit-animation-duration:.1ms;animation-duration:.1ms;-webkit-animation-name:mui-node-inserted;animation-name:mui-node-inserted}#mui-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:99999999;background-color:rgba(0,0,0,.2);overflow:auto}@-webkit-keyframes mui-node-inserted{from{opacity:.99}to{opacity:1}}@keyframes mui-node-inserted{from{opacity:.99}to{opacity:1}}.mui--no-transition{transition:none!important}.mui--no-user-select{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mui-caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.mui--text-left{text-align:left!important}.mui--text-right{text-align:right!important}.mui--text-center{text-align:center!important}.mui--text-justify{text-align:justify!important}.mui--text-nowrap{white-space:nowrap!important}.mui--align-baseline{vertical-align:baseline!important}.mui--align-top{vertical-align:top!important}.mui--align-middle{vertical-align:middle!important}.mui--align-bottom{vertical-align:bottom!important}.mui--text-dark{color:rgba(0,0,0,.87)}.mui--text-dark-secondary{color:rgba(0,0,0,.54)}.mui--text-dark-hint{color:rgba(0,0,0,.38)}.mui--text-light{color:#FFF}.mui--text-light-secondary{color:rgba(255,255,255,.7)}.mui--text-light-hint{color:rgba(255,255,255,.3)}.mui--text-accent{color:rgba(255,64,129,.87)}.mui--text-accent-secondary{color:rgba(255,64,129,.54)}.mui--text-accent-hint{color:rgba(255,64,129,.38)}.mui--text-black{color:#000}.mui--text-white{color:#FFF}.mui--text-danger{color:#F44336}.mui-list--unstyled{padding-left:0;list-style:none}.mui-list--inline{padding-left:0;list-style:none;margin-left:-5px}.mui-list--inline>li{display:inline-block;padding-left:5px;padding-right:5px}.mui--z1,.mui-dropdown__menu,.mui-select__menu{box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.mui--z2{box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23)}.mui--z3{box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}.mui--z4{box-shadow:0 14px 28px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.22)}.mui--z5{box-shadow:0 19px 38px rgba(0,0,0,.3),0 15px 12px rgba(0,0,0,.22)}.mui--clearfix:after,.mui--clearfix:before{content:" ";display:table}.mui--clearfix:after{clear:both}.mui--pull-right{float:right!important}.mui--pull-left{float:left!important}.mui--hide{display:none!important}.mui--show{display:block!important}.mui--invisible{visibility:hidden}.mui--overflow-hidden{overflow:hidden!important}.mui--overflow-hidden-x{overflow-x:hidden!important}.mui--overflow-hidden-y{overflow-y:hidden!important}.mui--visible-lg-block,.mui--visible-lg-inline,.mui--visible-lg-inline-block,.mui--visible-md-block,.mui--visible-md-inline,.mui--visible-md-inline-block,.mui--visible-sm-block,.mui--visible-sm-inline,.mui--visible-sm-inline-block,.mui--visible-xl-block,.mui--visible-xl-inline,.mui--visible-xl-inline-block,.mui--visible-xs-block,.mui--visible-xs-inline,.mui--visible-xs-inline-block{display:none!important}@media (max-width:543px){.mui-visible-xs{display:block!important}table.mui-visible-xs{display:table}tr.mui-visible-xs{display:table-row!important}td.mui-visible-xs,th.mui-visible-xs{display:table-cell!important}.mui--visible-xs-block{display:block!important}.mui--visible-xs-inline{display:inline!important}.mui--visible-xs-inline-block{display:inline-block!important}}@media (min-width:544px) and (max-width:767px){.mui-visible-sm{display:block!important}table.mui-visible-sm{display:table}tr.mui-visible-sm{display:table-row!important}td.mui-visible-sm,th.mui-visible-sm{display:table-cell!important}.mui--visible-sm-block{display:block!important}.mui--visible-sm-inline{display:inline!important}.mui--visible-sm-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.mui-visible-md{display:block!important}table.mui-visible-md{display:table}tr.mui-visible-md{display:table-row!important}td.mui-visible-md,th.mui-visible-md{display:table-cell!important}.mui--visible-md-block{display:block!important}.mui--visible-md-inline{display:inline!important}.mui--visible-md-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.mui-visible-lg{display:block!important}table.mui-visible-lg{display:table}tr.mui-visible-lg{display:table-row!important}td.mui-visible-lg,th.mui-visible-lg{display:table-cell!important}.mui--visible-lg-block{display:block!important}.mui--visible-lg-inline{display:inline!important}.mui--visible-lg-inline-block{display:inline-block!important}}@media (min-width:1200px){.mui-visible-xl{display:block!important}table.mui-visible-xl{display:table}tr.mui-visible-xl{display:table-row!important}td.mui-visible-xl,th.mui-visible-xl{display:table-cell!important}.mui--visible-xl-block{display:block!important}.mui--visible-xl-inline{display:inline!important}.mui--visible-xl-inline-block{display:inline-block!important}}@media (max-width:543px){.mui--hidden-xs{display:none!important}}@media (min-width:544px) and (max-width:767px){.mui--hidden-sm{display:none!important}}@media (min-width:768px) and (max-width:991px){.mui--hidden-md{display:none!important}}@media (min-width:992px) and (max-width:1199px){.mui--hidden-lg{display:none!important}}@media (min-width:1200px){.mui--hidden-xl{display:none!important}}body.mui-body--scroll-lock{overflow:hidden!important} diff --git a/O-BrandServer/server/css/obrand.css b/O-BrandServer/server/css/obrand.css new file mode 100644 index 0000000..1fd9a5c --- /dev/null +++ b/O-BrandServer/server/css/obrand.css @@ -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; + + } diff --git a/O-BrandServer/server/css/pure.min.css b/O-BrandServer/server/css/pure.min.css new file mode 100644 index 0000000..016c54b --- /dev/null +++ b/O-BrandServer/server/css/pure.min.css @@ -0,0 +1,11 @@ +/*! +Pure v0.6.0 +Copyright 2014 Yahoo! Inc. All rights reserved. +Licensed under the BSD License. +https://github.com/yahoo/pure/blob/master/LICENSE.md +*/ +/*! +normalize.css v^3.0 | MIT License | git.io/normalize +Copyright (c) Nicolas Gallagher and Jonathan Neal +*/ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.hidden,[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex;-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap;-ms-align-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5,.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12,.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24,.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8,.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%}.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%;*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%}.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%}.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12,.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12,.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset;border-color:#000\9}.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus,.pure-button-disabled:active{border:0;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus,.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus,.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;border-color:#129FEA}.pure-form input:not([type]):focus{outline:0;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus,.pure-form input[type=checkbox]:focus{outline:thin solid #129FEA;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=text][disabled],.pure-form input[type=password][disabled],.pure-form input[type=email][disabled],.pure-form input[type=url][disabled],.pure-form input[type=date][disabled],.pure-form input[type=month][disabled],.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled],.pure-form input[type=number][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background-color:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#e9322d}.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus,.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{height:2.25em;border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=text],.pure-form-stacked input[type=password],.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date],.pure-form-stacked input[type=month],.pure-form-stacked input[type=time],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=week],.pure-form-stacked input[type=number],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color],.pure-form-stacked input[type=file],.pure-form-stacked select,.pure-form-stacked label,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select,.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 11em}.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input,.pure-form .pure-group textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus,.pure-form .pure-group textarea:focus{z-index:3}.pure-form .pure-group input:first-child,.pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0}.pure-form .pure-group input:first-child:last-child,.pure-form .pure-group textarea:first-child:last-child{top:1px;border-radius:4px;margin:0}.pure-form .pure-group input:last-child,.pure-form .pure-group textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline,.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text],.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url],.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time],.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week],.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-menu-fixed{position:fixed;left:0;top:0;z-index:3}.pure-menu-list,.pure-menu-item{position:relative}.pure-menu-list{list-style:none;margin:0;padding:0}.pure-menu-item{padding:0;margin:0;height:100%}.pure-menu-link,.pure-menu-heading{display:block;text-decoration:none;white-space:nowrap}.pure-menu-horizontal{width:100%;white-space:nowrap}.pure-menu-horizontal .pure-menu-list{display:inline-block}.pure-menu-horizontal .pure-menu-item,.pure-menu-horizontal .pure-menu-heading,.pure-menu-horizontal .pure-menu-separator{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu-item .pure-menu-item{display:block}.pure-menu-children{display:none;position:absolute;left:100%;top:0;margin:0;padding:0;z-index:3}.pure-menu-horizontal .pure-menu-children{left:0;top:auto;width:inherit}.pure-menu-allow-hover:hover>.pure-menu-children,.pure-menu-active>.pure-menu-children{display:block;position:absolute}.pure-menu-has-children>.pure-menu-link:after{padding-left:.5em;content:"\25B8";font-size:small}.pure-menu-horizontal .pure-menu-has-children>.pure-menu-link:after{content:"\25BE"}.pure-menu-scrollable{overflow-y:scroll;overflow-x:hidden}.pure-menu-scrollable .pure-menu-list{display:block}.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list{display:inline-block}.pure-menu-horizontal.pure-menu-scrollable{white-space:nowrap;overflow-y:hidden;overflow-x:auto;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;padding:.5em 0}.pure-menu-horizontal.pure-menu-scrollable::-webkit-scrollbar{display:none}.pure-menu-separator{background-color:#ccc;height:1px;margin:.3em 0}.pure-menu-horizontal .pure-menu-separator{width:1px;height:1.3em;margin:0 .3em}.pure-menu-heading{text-transform:uppercase;color:#565d64}.pure-menu-link{color:#777}.pure-menu-children{background-color:#fff}.pure-menu-link,.pure-menu-disabled,.pure-menu-heading{padding:.5em 1em}.pure-menu-disabled{opacity:.5}.pure-menu-disabled .pure-menu-link:hover{background-color:transparent}.pure-menu-active>.pure-menu-link,.pure-menu-link:hover,.pure-menu-link:focus{background-color:#eee}.pure-menu-selected .pure-menu-link,.pure-menu-selected .pure-menu-link:visited{color:#000}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child,.pure-table th:first-child{border-left-width:0}.pure-table thead{background-color:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child>td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child>td{border-bottom-width:0} diff --git a/O-BrandServer/server/index.js b/O-BrandServer/server/index.js new file mode 100644 index 0000000..d4cc39f --- /dev/null +++ b/O-BrandServer/server/index.js @@ -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); }); + +}; diff --git a/O-BrandServer/server/units/db-accounts.js b/O-BrandServer/server/units/db-accounts.js new file mode 100644 index 0000000..8dc351e --- /dev/null +++ b/O-BrandServer/server/units/db-accounts.js @@ -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; +}; + diff --git a/O-BrandServer/server/units/db-company.js b/O-BrandServer/server/units/db-company.js new file mode 100644 index 0000000..b8c3baf --- /dev/null +++ b/O-BrandServer/server/units/db-company.js @@ -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; +}; diff --git a/O-BrandServer/server/units/db-connector.js b/O-BrandServer/server/units/db-connector.js new file mode 100644 index 0000000..3afd4f5 --- /dev/null +++ b/O-BrandServer/server/units/db-connector.js @@ -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); + diff --git a/O-BrandServer/server/units/db-pages.js b/O-BrandServer/server/units/db-pages.js new file mode 100644 index 0000000..4e51371 --- /dev/null +++ b/O-BrandServer/server/units/db-pages.js @@ -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; + +}; diff --git a/O-BrandServer/server/units/md-errors.js b/O-BrandServer/server/units/md-errors.js new file mode 100644 index 0000000..b0efbc6 --- /dev/null +++ b/O-BrandServer/server/units/md-errors.js @@ -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; diff --git a/O-BrandServer/views/pages.jade b/O-BrandServer/views/pages.jade new file mode 100644 index 0000000..9a7f037 --- /dev/null +++ b/O-BrandServer/views/pages.jade @@ -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 diff --git a/O-BrandServer/wwwroot/crossdomain.xml b/O-BrandServer/wwwroot/crossdomain.xml new file mode 100644 index 0000000..0c16a7a --- /dev/null +++ b/O-BrandServer/wwwroot/crossdomain.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/O-BrandServer/wwwroot/images/skyview-9e18406779ed06ffa74d29e9520dd870.jpg b/O-BrandServer/wwwroot/images/skyview-9e18406779ed06ffa74d29e9520dd870.jpg new file mode 100644 index 0000000..bf044bc Binary files /dev/null and b/O-BrandServer/wwwroot/images/skyview-9e18406779ed06ffa74d29e9520dd870.jpg differ diff --git a/O-BrandServer/wwwroot/index.html b/O-BrandServer/wwwroot/index.html new file mode 100644 index 0000000..5a7ecd2 --- /dev/null +++ b/O-BrandServer/wwwroot/index.html @@ -0,0 +1,26 @@ + + + + + + ObrandAdmin + + + + + + + + + + + + + + + + + + + + diff --git a/O-BrandServer/wwwroot/robots.txt b/O-BrandServer/wwwroot/robots.txt new file mode 100644 index 0000000..f591645 --- /dev/null +++ b/O-BrandServer/wwwroot/robots.txt @@ -0,0 +1,3 @@ +# http://www.robotstxt.org +User-agent: * +Disallow: diff --git a/server/app/pages.js b/server/app/pages.js index b09665b..68e9588 100644 --- a/server/app/pages.js +++ b/server/app/pages.js @@ -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); diff --git a/server/index.js b/server/index.js index d4cc39f..ee6f01d 100644 --- a/server/index.js +++ b/server/index.js @@ -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); diff --git a/server/units/db-accounts.js b/server/units/db-accounts.js index 8dc351e..e476a39 100644 --- a/server/units/db-accounts.js +++ b/server/units/db-accounts.js @@ -183,8 +183,7 @@ module.exports = function(db) { }); }); }; - - //MakeMemberOf(cid, uid) + module.makeMemberOf = function(cid, uid) { return new Promise((resolve, reject) => { this.sqlMakeMemberOf(cid, uid) diff --git a/server/units/db-company.js b/server/units/db-company.js index b8c3baf..0708deb 100644 --- a/server/units/db-company.js +++ b/server/units/db-company.js @@ -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]) diff --git a/server/units/db-pages.js b/server/units/db-pages.js index 4e51371..4a24c12 100644 --- a/server/units/db-pages.js +++ b/server/units/db-pages.js @@ -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); }