Server
+User Agent
+ {ua} +{uaParsed|jsp}
+
+ Headers
+ +{headers|jsp}
+
+ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1359da1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gulp"] + path = gulp + url = git@github.com:thecodebureau/gulp.git diff --git a/app.js b/app.js deleted file mode 100644 index 9247cc3..0000000 --- a/app.js +++ /dev/null @@ -1,25 +0,0 @@ -var express = require('express'); -var UAParser = require('ua-parser-js'); -var app = express(); -var parser = new UAParser(); -var dust = require('dustjs-linkedin'); -var fs = require('fs'); - -fs.readFile('./index.dust', function(error, data){ - dust.loadSource(dust.compile(data.toString(), 'index')); -}); - -var modern = '
'; - -app.use(function(request, response){ - parser.setUA(request.get('user-agent')); - dust.render('index', {ua: JSON.stringify(parser.getResult(), null, 2)}, function(error, out){ - response.write(out); - response.end(); - }); - -}); - -app.listen(3993, function(){ - console.log("App listening on port 3993."); -}); diff --git a/gulp b/gulp new file mode 160000 index 0000000..05881fd --- /dev/null +++ b/gulp @@ -0,0 +1 @@ +Subproject commit 05881fd4a1af2f0ab2983d52605e28db643c3fc3 diff --git a/gulpconfig.js b/gulpconfig.js new file mode 100644 index 0000000..4f58927 --- /dev/null +++ b/gulpconfig.js @@ -0,0 +1,112 @@ +module.exports = { + "autoprefixer": { + "browsers": [ + "safari >= 5", + "ie >= 8", + "ios >= 6", + "opera >= 12.1", + "firefox >= 17", + "chrome >= 30", + "android >= 4" + ], + "cascade": true + }, + "bower": { + "src": "/home/sup3rman/dev/browser/bower_components", + "dest": "/home/sup3rman/dev/browser/public/js/bower" + }, + "browserSync": { + "browser": "chromium", + "ghostMode": false, + "proxy": "localhost:3810", + "files": [ + "/home/sup3rman/dev/browser/public/css/**/*.css", + "/home/sup3rman/dev/browser/public/js/**/*.js" + ] + }, + "browserify": { + "debug": true, + "dest": "/home/sup3rman/dev/browser/public/js", + "entries": [ + "app.js", + "admin.js" + ], + "paths": [ + "/home/sup3rman/dev/browser/node_modules", + "/home/sup3rman/dev/browser/modules" + ], + "outputs": [ + "app.js", + "admin.js" + ], + "src": "/home/sup3rman/dev/browser/src/js" + }, + "fonts": { + "src": "/home/sup3rman/dev/browser/src/fonts/**/*.{eot,ttf,woff}", + "dest": "/home/sup3rman/dev/browser/public/fonts" + }, + "nodemon": { + "ext": "js,dust", + "ignore": [ + "bower_components", + "gulp", + "node_modules", + "public", + "samples", + "src" + ], + "reloadDelay": 300, + "script": "./server/server.js" + }, + "raster": { + "src": "/home/sup3rman/dev/browser/src/raster/**/*.{png,gif,jpg}", + "dest": "/home/sup3rman/dev/browser/public/img" + }, + "sass": { + "src": "/home/sup3rman/dev/browser/src/sass/**/*.{sass,scss}", + "dest": "/home/sup3rman/dev/browser/public/css", + "options": { + "outputStyle": "nested", + "includePaths": [ + "./node_modules/spysass/sass" + ], + "imagePath": "../img" + } + }, + "static": { + "src": "/home/sup3rman/dev/browser/src/static/**/*", + "dest": "/home/sup3rman/dev/browser/public" + }, + "tasks": { + "default": [ + "wipe", + [ + "bower", + "browserify", + "fonts", + "nodemon", + "raster", + "sass", + "static", + "svg" + ], + [ + "watch", + "browser-sync" + ] + ] + }, + "svg": { + "src": "/home/sup3rman/dev/browser/src/svg/**/*.svg", + "dest": "/home/sup3rman/dev/browser/public/img" + }, + "watch": { + "browserify": "/home/sup3rman/dev/browser/src/js/**/*.js", + "sass": "/home/sup3rman/dev/browser/src/sass/**/*.{sass,scss}" + }, + "wipe": { + "src": [ + "/home/sup3rman/dev/browser/public" + ] + } +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 120000 index 0000000..0f1e7d6 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1 @@ +gulp/gulpfile.js \ No newline at end of file diff --git a/index.dust b/index.dust deleted file mode 100644 index b501234..0000000 --- a/index.dust +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -
- {ua}
-
-
-
-
\ No newline at end of file
diff --git a/nodemon.json b/nodemon.json
new file mode 100644
index 0000000..91d1562
--- /dev/null
+++ b/nodemon.json
@@ -0,0 +1,11 @@
+{
+ "ext": "js,dust",
+ "ignore": [
+ "bower_components",
+ "gulp",
+ "node_modules",
+ "public",
+ "samples",
+ "src"
+ ]
+}
diff --git a/package.json b/package.json
index 6ee58b0..3ede1fc 100644
--- a/package.json
+++ b/package.json
@@ -2,18 +2,14 @@
"name": "browser",
"version": "0.1.0",
"description": "",
- "main": "app.js",
- "dependencies": {
- "dustjs-linkedin": "^2.7.2",
- "express": "^4.13.3",
- "ua-parser-js": "^0.7.9"
- },
- "devDependencies": {},
- "scripts": {},
- "repository": {
- "type": "git",
- "url": "gituser@git.thecodebureau.com:tcb/browser"
+ "main": "./server/server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
},
"author": "The Code Bureau ');
+ $pre.text(JSON.stringify(value, null, 2));
+ $div.append($pre);
+ });
+
+
+ // TODO maybe have server send Headers from AJAX request
+ var id = window.location.search ? window.location.search.split('=')[1] : 'null';
+
+ var path = window.location.protocol + '//' + window.location.host + '/api/fingerprints/' + id;
+
+ console.log(path);
+ $.ajax({
+ method: 'POST',
+ dataType: 'json',
+ data: device,
+ url: path,
+ success: function(res) {
+ var key = 'headers';
+ $div.append($('' + key + '
'));
+ var $pre = $('');
+ $pre.text(JSON.stringify(res.headers, null, 2));
+ $div.append($pre);
+ console.log('success');
+ },
+ error: function() {
+ console.log('error');
+ }
+ });
+});
+
+},{}]},{},[2])
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9mYWN0b3ItYnVuZGxlL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvanMvYXBwLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIkKGZ1bmN0aW9uKCkge1xuXHR2YXIgZGV2aWNlID0ge307XG5cblx0dmFyIG5hdiA9IF8uY2xvbmUod2luZG93Lm5hdmlnYXRvcik7XG5cblx0bmF2LnBsdWdpbnMgPSBfLm1hcChuYXZpZ2F0b3IucGx1Z2lucywgZnVuY3Rpb24ob2JqLCBrZXkpIHtcblx0XHRyZXR1cm4gb2JqLm5hbWUgKyAnICgnICsgb2JqLmZpbGVuYW1lICsgJyknO1xuXHR9KTtcblxuXHQvL2RldmljZS5uYXZpZ2F0b3IgPSBfLm9taXQobmF2LCBbXG5cdC8vXHQnYXBwQ29kZU5hbWUnLFxuXHQvL1x0J2FwcE1pbm9yVmVyc2lvbicsXG5cdC8vXHQnYXBwTmFtZScsXG5cdC8vXHQnYXBwVmVyc2lvbicsXG5cdC8vXHQnYmF0dGVyeScsXG5cdC8vXHQnY3B1Q2xhc3MnLFxuXHQvL1x0J2dlb2xvY2F0aW9uJyxcblx0Ly9cdCdtaW1lVHlwZXMnLFxuXHQvL1x0J29zY3B1Jyxcblx0Ly9cdCdwbGF0Zm9ybScsXG5cdC8vXHQncHJvZHVjdCcsXG5cdC8vXHQndmVuZG9yJyxcblx0Ly9cdCd2ZW5kb3JTdWInXG5cdC8vXSk7XG5cdGRldmljZS5uYXZpZ2F0b3IgPSBfLnBpY2sobmF2LCBbXG5cdFx0J2Nvb2tpZUVuYWJsZWQnLFxuXHRcdCdkb05vdFRyYWNrJyxcblx0XHQnaGFyZHdhcmVDb25jdXJyZW5jeScsXG5cdFx0J2xhbmd1YWdlJyxcblx0XHQnbGFuZ3VhZ2VzJyxcblx0XHQnbWF4VG91Y2hQb2ludHMnLFxuXHRcdCdvbkxpbmUnLFxuXHRcdCdwbHVnaW5zJyxcblx0XHQncHJvZHVjdFN1YicsXG5cdFx0J2Jyb3dzZXJMYW5ndWFnZScsXG5cdFx0J3N5c3RlbUxhbmd1YWdlJyxcblx0XHQndXNlckxhbmd1YWdlJyxcblx0XHQndXNlckFnZW50J1xuXHRdKTtcblxuXHRkZXZpY2Uuc2NyZWVuID0gXy5waWNrKHdpbmRvdy5zY3JlZW4sIFtcblx0XHRcImF2YWlsSGVpZ2h0XCIsXG5cdFx0XCJhdmFpbExlZnRcIixcblx0XHRcImF2YWlsVG9wXCIsXG5cdFx0XCJhdmFpbFdpZHRoXCIsXG5cdFx0XCJjb2xvckRlcHRoXCIsXG5cdFx0XCJoZWlnaHRcIixcblx0XHRcInBpeGVsRGVwdGhcIixcblx0XHRcIndpZHRoXCJcblx0XSk7XG5cblx0ZGV2aWNlLnNjcmVlbi5ib2R5ID0gXy5waWNrKGRvY3VtZW50LmJvZHksICdjbGllbnRXaWR0aCcsICdjbGllbnRIZWlnaHQnLCAnb2Zmc2V0V2lkdGgnLCAnb2Zmc2V0SGVpZ2h0JywgJ3Njcm9sbFdpZHRoJywgJ3Njcm9sbEhlaWdodCcpO1xuXHRkZXZpY2Uuc2NyZWVuLnBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcblxuXHR2YXIgb3JpZW50YXRpb24gPSB3aW5kb3cuc2NyZWVuLm9yaWVudGF0aW9uIHx8IHdpbmRvdy5zY3JlZW4ubW96T3JpZW50YXRpb24gfHwgd2luZG93LnNjcmVlbi5tc09yaWVudGF0aW9uO1xuXG5cdGlmKCFfLmlzU3RyaW5nKG9yaWVudGF0aW9uKSlcblx0XHRvcmllbnRhdGlvbiA9IF8ucGljayhvcmllbnRhdGlvbiwgWyAndHlwZScsICdhbmdsZScgXSk7XG5cblx0ZGV2aWNlLnNjcmVlbi5vcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuXG5cdGRldmljZS5tb2Rlcm5penIgPSBfLmNvbXBhY3QoJChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmF0dHIoJ2NsYXNzJykuc3BsaXQoJyAnKSk7XG5cblx0Ly9uYXYuamF2YUVuYWJsZWQgPSBuYXYuamF2YUVuYWJsZWQoKTtcblx0dmFyICRkaXYgPSAkKCcjY29udGVudCcpO1xuXHRfLmVhY2goZGV2aWNlLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG5cdFx0JGRpdi5hcHBlbmQoJCgnPGgyPicgKyBrZXkgKyAnPC9oMj4nKSk7XG5cdFx0dmFyICRwcmUgPSAkKCc8cHJlIGlkPVwiJyArIGtleSArICdcIj4nKTtcblx0XHQkcHJlLnRleHQoSlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDIpKTtcblx0XHQkZGl2LmFwcGVuZCgkcHJlKTtcblx0fSk7XG5cblxuXHQvLyBUT0RPIG1heWJlIGhhdmUgc2VydmVyIHNlbmQgSGVhZGVycyBmcm9tIEFKQVggcmVxdWVzdFxuXHR2YXIgaWQgPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoID8gd2luZG93LmxvY2F0aW9uLnNlYXJjaC5zcGxpdCgnPScpWzFdIDogJ251bGwnO1xuXG5cdHZhciBwYXRoID0gd2luZG93LmxvY2F0aW9uLnByb3RvY29sICsgJy8vJyArIHdpbmRvdy5sb2NhdGlvbi5ob3N0ICsgJy9hcGkvZmluZ2VycHJpbnRzLycgKyBpZDtcblxuXHRjb25zb2xlLmxvZyhwYXRoKTtcblx0JC5hamF4KHtcblx0XHRtZXRob2Q6ICdQT1NUJyxcblx0XHRkYXRhVHlwZTogJ2pzb24nLFxuXHRcdGRhdGE6IGRldmljZSxcblx0XHR1cmw6IHBhdGgsXG5cdFx0c3VjY2VzczogZnVuY3Rpb24ocmVzKSB7XG5cdFx0XHR2YXIga2V5ID0gJ2hlYWRlcnMnO1xuXHRcdFx0JGRpdi5hcHBlbmQoJCgnPGgyPicgKyBrZXkgKyAnPC9oMj4nKSk7XG5cdFx0XHR2YXIgJHByZSA9ICQoJzxwcmUgaWQ9XCInICsga2V5ICsgJ1wiPicpO1xuXHRcdFx0JHByZS50ZXh0KEpTT04uc3RyaW5naWZ5KHJlcy5oZWFkZXJzLCBudWxsLCAyKSk7XG5cdFx0XHQkZGl2LmFwcGVuZCgkcHJlKTtcblx0XHRcdGNvbnNvbGUubG9nKCdzdWNjZXNzJyk7XG5cdFx0fSxcblx0XHRlcnJvcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnZXJyb3InKTtcblx0XHR9XG5cdH0pO1xufSk7XG4iXX0=
diff --git a/public/js/common.js b/public/js/common.js
new file mode 100644
index 0000000..dff1999
--- /dev/null
+++ b/public/js/common.js
@@ -0,0 +1 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o
+
+ Oops!
+ Ett problem har tyvärr uppstått.
+
{error.status} : {error.statusText}
+ {error.message}
+
{error.stack}
+
+
diff --git a/server/templates/pages/admin.dust b/server/templates/pages/admin.dust
new file mode 100644
index 0000000..9f2b974
--- /dev/null
+++ b/server/templates/pages/admin.dust
@@ -0,0 +1,23 @@
+
+
+ The Code Bureau : Browser Fingerprint
+
+
+
+
+
+
+
+
+
diff --git a/server/templates/pages/index.dust b/server/templates/pages/index.dust
new file mode 100644
index 0000000..6c556f4
--- /dev/null
+++ b/server/templates/pages/index.dust
@@ -0,0 +1,52 @@
+
+
+ The Code Bureau : Browser Fingerprint
+
+
+
+
+
+
+
+ Server
+ User Agent
+ {ua}
+ {uaParsed|jsp}
+
+ Headers
+
+ {headers|jsp}
+
+ Client
+
+
+
+
+
+
+
+
+
+
diff --git a/src/js/admin.js b/src/js/admin.js
new file mode 100644
index 0000000..3976e4f
--- /dev/null
+++ b/src/js/admin.js
@@ -0,0 +1,27 @@
+require('jquery-jsonify');
+
+var fairdice = require('fair-dice');
+
+$(function() {
+ $('form button.generate').on('click', function() {
+ console.log(fairdice.string());
+ $('form input[name="_id"]').val(fairdice.string(6));
+ });
+ $('form').on('submit', function(e) {
+ e.preventDefault();
+ var $form = $(this);
+
+ $.ajax({
+ url: $form.attr('action'),
+ dataType: 'json',
+ method: 'POST',
+ data: $form.JSONify(),
+ success: function(res) {
+ console.log('success');
+ console.log(res);
+ var path = window.location.protocol + '//' + window.location.host + '/?id=' + res._id;
+ $form.before('Added
' + path + '');
+ }
+ });
+ });
+});
diff --git a/src/js/app.js b/src/js/app.js
new file mode 100644
index 0000000..04868d6
--- /dev/null
+++ b/src/js/app.js
@@ -0,0 +1,97 @@
+$(function() {
+ var device = {};
+
+ var nav = _.clone(window.navigator);
+
+ nav.plugins = _.map(navigator.plugins, function(obj, key) {
+ return obj.name + ' (' + obj.filename + ')';
+ });
+
+ //device.navigator = _.omit(nav, [
+ // 'appCodeName',
+ // 'appMinorVersion',
+ // 'appName',
+ // 'appVersion',
+ // 'battery',
+ // 'cpuClass',
+ // 'geolocation',
+ // 'mimeTypes',
+ // 'oscpu',
+ // 'platform',
+ // 'product',
+ // 'vendor',
+ // 'vendorSub'
+ //]);
+ device.navigator = _.pick(nav, [
+ 'cookieEnabled',
+ 'doNotTrack',
+ 'hardwareConcurrency',
+ 'language',
+ 'languages',
+ 'maxTouchPoints',
+ 'onLine',
+ 'plugins',
+ 'productSub',
+ 'browserLanguage',
+ 'systemLanguage',
+ 'userLanguage',
+ 'userAgent'
+ ]);
+
+ device.screen = _.pick(window.screen, [
+ "availHeight",
+ "availLeft",
+ "availTop",
+ "availWidth",
+ "colorDepth",
+ "height",
+ "pixelDepth",
+ "width"
+ ]);
+
+ device.screen.body = _.pick(document.body, 'clientWidth', 'clientHeight', 'offsetWidth', 'offsetHeight', 'scrollWidth', 'scrollHeight');
+ device.screen.pixelRatio = window.devicePixelRatio;
+
+ var orientation = window.screen.orientation || window.screen.mozOrientation || window.screen.msOrientation;
+
+ if(!_.isString(orientation))
+ orientation = _.pick(orientation, [ 'type', 'angle' ]);
+
+ device.screen.orientation = orientation;
+
+ device.modernizr = _.compact($(document.documentElement).attr('class').split(' '));
+
+ //nav.javaEnabled = nav.javaEnabled();
+ var $div = $('#content');
+ _.each(device, function(value, key) {
+ $div.append($('' + key + '
'));
+ var $pre = $('');
+ $pre.text(JSON.stringify(value, null, 2));
+ $div.append($pre);
+ });
+
+
+ // TODO maybe have server send Headers from AJAX request
+ var id = window.location.search ? window.location.search.split('=')[1] : 'null';
+
+ var path = window.location.protocol + '//' + window.location.host + '/api/fingerprints/' + id;
+
+ console.log(path);
+ $.ajax({
+ method: 'POST',
+ dataType: 'json',
+ data: device,
+ url: path,
+ success: function(res) {
+ var key = 'headers';
+ $div.append($('' + key + '
'));
+ var $pre = $('');
+ $pre.text(JSON.stringify(res.headers, null, 2));
+ $div.append($pre);
+ console.log('success');
+ },
+ error: function() {
+ console.log('error');
+ }
+ });
+});