got forms to work without subdomains

This commit is contained in:
David Baldwynn 2017-03-27 17:04:03 -07:00
parent 8d27010d0a
commit 86c9c45670
No known key found for this signature in database
GPG key ID: 15D1C13202224A9B
14 changed files with 176 additions and 242 deletions

View file

@ -4,7 +4,8 @@
* Module dependencies.
*/
var forms = require('../../app/controllers/forms.server.controller'),
core = require('../../app/controllers/core.server.controller');
core = require('../../app/controllers/core.server.controller'),
config = require('../../config/config');
module.exports = function(app) {
// Core routing
@ -14,12 +15,24 @@ module.exports = function(app) {
app.route('/subdomain/api/')
.get(core.redoc);
app.route('/subdomain/:userSlug((?!api$)[A-Za-z0-9]+)/')
.get(core.form);
if(!config.subdomainsDisabled) {
app.route('/subdomain/:userSlug((?!api$)[A-Za-z0-9]+)/')
.get(core.form);
app.route('/subdomain/:userSlug((?!api$)[A-Za-z0-9]+)/forms/:formId([a-zA-Z0-9]+)')
.post(forms.createSubmission);
app.route('/subdomain/:userSlug((?!api$)[A-Za-z0-9]+)/forms/:formId([a-zA-Z0-9]+)')
.post(forms.createSubmission);
app.route('/subdomain/:userSlug((?!api$)[A-Za-z0-9]+)/forms/:formId([a-zA-Z0-9]+)/render')
.get(forms.readForRender);
app.route('/subdomain/:userSlug((?!api$)[A-Za-z0-9]+)/forms/:formId([a-zA-Z0-9]+)/render')
.get(forms.readForRender);
} else {
app.route('/view/')
.get(core.form);
app.route('/forms/:formId([a-zA-Z0-9]+)')
.post(forms.createSubmission);
app.route('/forms/:formId([a-zA-Z0-9]+)/render')
.get(forms.readForRender);
}
};

View file

@ -72,6 +72,7 @@
var signupDisabled = {{signupDisabled | safe}};
var socketPort = {{socketPort | safe}};
var socketUrl = {{socketUrl | safe}};
var subdomainsDisabled = {{subdomainsDisabled | safe}};
</script>
<!--Socket.io Client Dependency-->

View file

@ -72,6 +72,7 @@
<script type="text/javascript">
var signupDisabled = {{signupDisabled | safe}};
var socketPort = {{socketPort | safe}};
var subdomainsDisabled = {{subdomainsDisabled | safe}};
</script>
<!--Socket.io Client Dependency-->

2
config/env/all.js vendored
View file

@ -35,6 +35,8 @@ module.exports = {
mailbox_id: process.env.MAILOSAUR_MAILBOX || ''
},
subdomainsDisabled: (process.env.SUBDOMAINS_DISABLED == "TRUE"),
//Sentry DSN Client Key
DSN: process.env.RAVEN_DSN || '',

View file

@ -57,6 +57,8 @@ module.exports = function(db) {
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.subdomainsDisabled = config.subdomainsDisabled;
if(config.socketPort){
app.locals.socketPort = config.socketPort;
} else {
@ -77,80 +79,91 @@ module.exports = function(db) {
app.locals.cssFiles = config.getCSSAssets();
app.use(function (req, res, next) {
var User = mongoose.model('User');
var path = '/' + 'subdomain' + '/';
var subdomains = req.subdomains;
var host = req.hostname;
if(subdomains.slice(0, 4).join('.')+'' === '1.0.0.127'){
subdomains = subdomains.slice(4);
}
if(!config.subdomainsDisabled) {
var User = mongoose.model('User');
var path = '/' + 'subdomain' + '/';
var subdomains = req.subdomains;
var host = req.hostname;
// continue if no subdomains
if (!subdomains.length) return next();
var urlPath = url.parse(req.url).path.split('/');
if(urlPath.indexOf('static') > -1){
//console.log("STATIC FILE\n\n\n\n");
urlPath.splice(1,1);
req.root = 'https://' + config.baseUrl + urlPath.join('/');
console.log(req.root);
return next();
}
if(urlPath.indexOf('users') > -1 && urlPath.indexOf('me') > -1){
return next();
}
if(subdomains.indexOf('stage') > -1 || subdomains.indexOf('admin') > -1){
return next();
}
console.log(req.subdomains.reverse()[0]);
//console.log("is api subdomain: "+ (subdomains.indexOf("api") > -1));
//console.log(req.url);
if(subdomains.indexOf('api') > -1){
// rebuild url
path += 'api' + req.url;
console.log(req.url);
// TODO: check path and query strings are preserved
// reassign url
req.url = path;
console.log(req.url);
return next();
}
User.findOne({username: req.subdomains.reverse()[0]}).exec(function (err, user) {
if (err) {
console.log(err);
req.subdomains = null;
// Error page
return res.status(404).render('404', {
error: 'Page Does Not Exist'
});
}
if (user === null){
// Error page
return res.status(404).render('404', {
error: 'Page Does Not Exist'
});
if (subdomains.slice(0, 4).join('.') + '' === '1.0.0.127') {
subdomains = subdomains.slice(4);
}
// rebuild url
path += subdomains.join('/') + req.url;
// continue if no subdomains
if (!subdomains.length) return next();
// TODO: check path and query strings are preserved
// reassign url
console.log("path: "+path);
req.url = path;
var urlPath = url.parse(req.url).path.split('/');
if (urlPath.indexOf('static') > -1) {
urlPath.splice(1, 1);
if(process.env.NODE_ENV == 'development'){
req.root = req.protocol + '://' + config.baseUrl + ':' + config.port + urlPath.join('/');
} else {
req.root = req.protocol + '://' + config.baseUrl + urlPath.join('/');
}
return next();
}
req.userId = user._id;
if (urlPath.indexOf('users') > -1 && urlPath.indexOf('me') > -1) {
return next();
}
// Q.E.D.
next();
});
if (subdomains.indexOf('stage') > -1 || subdomains.indexOf('admin') > -1) {
return next();
}
if (subdomains.indexOf('api') > -1) {
// rebuild url
path += 'api' + req.url;
// TODO: check path and query strings are preserved
// reassign url
req.url = path;
return next();
}
User.findOne({username: req.subdomains.reverse()[0]}).exec(function (err, user) {
if (err) {
console.log(err);
req.subdomains = null;
// Error page
return res.status(404).render('404', {
error: 'Page Does Not Exist'
});
}
if (user === null) {
// Error page
return res.status(404).render('404', {
error: 'Page Does Not Exist'
});
}
// rebuild url
path += subdomains.join('/') + req.url;
// TODO: check path and query strings are preserved
// reassign url
console.log("path: " + path);
req.url = path;
req.userId = user._id;
// Q.E.D.
next();
});
} else {
var urlPath = url.parse(req.url).path.split('/');
if (urlPath.indexOf('static') > -1 && urlPath.indexOf('view') === urlPath.indexOf('static')-1) {
urlPath.splice(1, 1);
req.url = urlPath.join('/');
console.log('\n\n\nreq.url: ' + req.url);
return next();
}
return next();
}
});
//Setup Prerender.io

View file

@ -1,8 +1,8 @@
'use strict';
// Forms controller
angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm', '$http', '$uibModal', 'myForm', '$filter', '$sce',
function($rootScope, $scope, $stateParams, $state, Forms, CurrentForm, $http, $uibModal, myForm, $filter, $sce) {
angular.module('forms').controller('AdminFormController', ['$rootScope', '$window', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm', '$http', '$uibModal', 'myForm', '$filter', '$sce',
function($rootScope, $window, $scope, $stateParams, $state, Forms, CurrentForm, $http, $uibModal, myForm, $filter, $sce) {
$scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
@ -25,10 +25,14 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope
$scope.formURL = "/#!/forms/" + $scope.myform._id;
if(window.location.host.split('.').length < 3){
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host + $scope.formURL;
if($window.subdomainsDisabled == true){
$scope.actualFormURL = window.location.protocol + '//' + window.location.host + $scope.formURL;
} else {
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host.split('.').slice(1,3).join('.') + $scope.formURL;
if(window.location.host.split('.').length < 3){
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host + $scope.formURL;
} else {
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host.split('.').slice(1,3).join('.') + $scope.formURL;
}
}
var refreshFrame = $scope.refreshFrame = function(){

View file

@ -1,4 +0,0 @@
{
"directory": "demo/lib",
"analytics": false
}

View file

@ -1,3 +0,0 @@
dist
demo/lib
node_modules

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 tellform
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,12 +0,0 @@
# angular-tellform
Tellform Angular Form UI Module
##About
This module gives you the standalone front-end of tellform. It handles form rendering and form ui. For you to use this module you must have an API endpoint, such as (Formkeep)[https://formkeep.com].
This is a readonly split of the tellform project.
To see it in action clone this repos, run `npm install` and open the file `demo/index.html`.
##Disclaimer
This is a largely work in progress, use it at your own risk.

View file

@ -1,44 +0,0 @@
{
"name": "tellform Form UI",
"description": "Opensource alternative to TypeForm",
"version": "1.2.1",
"homepage": "https://github.com/whitef0x0/tellform",
"authors": [
"David Baldwynn <polydaic@gmail.com> (http://baldwynn.me)",
"Samuel Laulhau <sam@lalop.co> (https://samuellaulhau.fr)"
],
"license": "MIT",
"dependencies": {
"bootstrap": "~3",
"angular": "~1.4.7",
"angular-translate": "~2.11.0",
"angular-resource": "~1.4.7",
"angular-bootstrap": "~1.3.2",
"angular-ui-utils": "~3.0.0",
"ng-file-upload": "~10.0.2",
"angular-ui-date": "~0.0.8",
"lodash": "~3.10.0",
"angular-input-stars": "https://github.com/whitef0x0/angular-input-stars.git#master",
"file-saver.js": "~1.20150507.2",
"angular-scroll": "^1.0.0",
"ui-select": "angular-ui-select#^0.16.1",
"angular-sanitize": "^1.5.3",
"v-button": "^1.1.1",
"angular-busy": "^4.1.3",
"font-awesome": "~4.6.1",
"components-font-awesome": "~4.6.1",
"angular-strap": "~2.3.8",
"restangular": "~1.5.2"
},
"resolutions": {
"angular-bootstrap": "^0.14.0",
"angular": "1.4.x"
"restangular": "~1.5.2",
"angular-ui-select": "whitef0x0/ui-select#compiled",
},
"overrides": {
"BOWER-PACKAGE": {
"main": "**/*.min.js"
}
}
}

View file

@ -1,47 +0,0 @@
'use strict';
module.exports = function(grunt) {
require('jit-grunt')(grunt);
// Project Configuration
grunt.initConfig({
ngAnnotate: {
production: {
files: {
'dist/form.js': [
'config/**/*.js', 'controllers/**/*.js',
'directives/**/*.js', 'services/**/*.js',
'dist/template.js'
]
}
}
},
html2js: {
options: {
base: '',
module: 'TellForm.templates',
singleModule: true,
rename: function (moduleName) {
return 'modules/forms/base/' + moduleName;
}
},
form: {
src: ['views/**/*.html'],
dest: 'dist/template.js'
}
},
cssmin: {
combine: {
files: {
'dist/form.css': 'css/**/*.css'
}
}
},
});
// Making grunt default to force in order not to break the project.
grunt.option('force', true);
// Default task(s).
grunt.registerTask('default', ['html2js:form', 'ngAnnotate', 'cssmin']);
};

View file

@ -1,33 +0,0 @@
{
"name": "angular-tellform",
"description": "Opensource alternative to TypeForm",
"version": "1.3.0",
"homepage": "https://github.com/whitef0x0/tellform",
"authors": [
"David Baldwynn <polydaic@gmail.com> (http://baldwynn.me)",
"Samuel Laulhau <sam@lalop.co> (https://samuellaulhau.fr)"
],
"private": true,
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/tellform/angular-tellform.git"
},
"engines": {
"node": "~5.0.0",
"npm": "~2.11.2"
},
"scripts": {
"postinstall": "node node_modules/.bin/bower install --config.interactive=false; node node_modules/.bin/grunt build"
},
"dependencies": {
"bower": "~1.6.5",
"grunt": "~0.4.1",
"grunt-cli": "~0.1.13",
"grunt-contrib-cssmin": "~0.14.0",
"grunt-contrib-uglify": "~0.11.0",
"grunt-html2js": "~0.3.5",
"grunt-ng-annotate": "~1.0.1",
"jit-grunt": "^0.10.0"
}
}

View file

@ -0,0 +1,64 @@
(function () {
'use strict';
// Create the Socket.io wrapper service
angular
.module('forms')
.factory('Socket', Socket);
Socket.$inject = ['$timeout', '$window'];
function Socket($timeout, $window) {
var service = {
connect: connect,
emit: emit,
on: on,
removeListener: removeListener,
socket: null
};
var url = '';
if($window.socketPort && $window.socketUrl){
url = $window.socketUrl + ':' + $window.socketPort;
} else if ($window.socketUrl && !$window.socketUrl){
url = $window.socketUrl;
} else if ($window.socketPort){
url = window.location.protocol+'//'+window.location.hostname + ':' + $window.socketPort;
} else {
url = window.location.protocol+'//'+window.location.hostname;
}
connect(url);
return service;
// Connect to Socket.io server
function connect(url) {
service.socket = io(url, {'transports': ['websocket', 'polling']});
}
// Wrap the Socket.io 'emit' method
function emit(eventName, data) {
if (service.socket) {
service.socket.emit(eventName, data);
}
}
// Wrap the Socket.io 'on' method
function on(eventName, callback) {
if (service.socket) {
service.socket.on(eventName, function (data) {
$timeout(function () {
callback(data);
});
});
}
}
// Wrap the Socket.io 'removeListener' method
function removeListener(eventName) {
if (service.socket) {
service.socket.removeListener(eventName);
}
}
}
}());