├── RedSnap
├── RedSnap
│ ├── bin
│ │ ├── node.cmd
│ │ ├── www
│ │ ├── ChangeConfig.ps1
│ │ ├── setup_web.cmd
│ │ └── download.ps1
│ ├── IISNode.yml
│ ├── public
│ │ ├── views
│ │ │ ├── logout.html
│ │ │ ├── cam
│ │ │ │ ├── snapcanvas.html
│ │ │ │ ├── view.html
│ │ │ │ └── draw.html
│ │ │ ├── main.html
│ │ │ ├── snapModal.html
│ │ │ ├── register.html
│ │ │ ├── friends.html
│ │ │ └── login.html
│ │ ├── images
│ │ │ ├── snap.png
│ │ │ ├── favicon.ico
│ │ │ └── spinner.gif
│ │ ├── stylesheets
│ │ │ ├── style.styl
│ │ │ └── style.css
│ │ ├── javascripts
│ │ │ ├── services
│ │ │ │ ├── Snap.js
│ │ │ │ ├── Friend.js
│ │ │ │ ├── Session.js
│ │ │ │ ├── SnapView.js
│ │ │ │ ├── User.js
│ │ │ │ ├── SnapService.js
│ │ │ │ ├── FriendService.js
│ │ │ │ ├── Auth.js
│ │ │ │ └── http-auth-interceptor.js
│ │ │ ├── controllers
│ │ │ │ ├── cam.js
│ │ │ │ ├── logout.js
│ │ │ │ ├── register.js
│ │ │ │ ├── login.js
│ │ │ │ ├── friends.js
│ │ │ │ ├── cam
│ │ │ │ │ ├── view.js
│ │ │ │ │ └── draw.js
│ │ │ │ └── main.js
│ │ │ ├── directives
│ │ │ │ ├── canvas.js
│ │ │ │ └── webcam.js
│ │ │ ├── core.js
│ │ │ └── providers
│ │ │ │ └── socket.js
│ │ └── index.html
│ ├── obj
│ │ └── Release
│ │ │ └── Package
│ │ │ └── PackageTmp
│ │ │ └── public
│ │ │ ├── views
│ │ │ ├── logout.html
│ │ │ ├── cam
│ │ │ │ ├── snapcanvas.html
│ │ │ │ ├── view.html
│ │ │ │ └── draw.html
│ │ │ ├── main.html
│ │ │ ├── snapModal.html
│ │ │ ├── register.html
│ │ │ ├── friends.html
│ │ │ └── login.html
│ │ │ ├── images
│ │ │ ├── snap.png
│ │ │ ├── favicon.ico
│ │ │ └── spinner.gif
│ │ │ ├── javascripts
│ │ │ ├── services
│ │ │ │ ├── Snap.js
│ │ │ │ ├── Friend.js
│ │ │ │ ├── Session.js
│ │ │ │ ├── SnapView.js
│ │ │ │ ├── User.js
│ │ │ │ ├── SnapService.js
│ │ │ │ ├── FriendService.js
│ │ │ │ ├── Auth.js
│ │ │ │ └── http-auth-interceptor.js
│ │ │ ├── controllers
│ │ │ │ ├── cam.js
│ │ │ │ ├── logout.js
│ │ │ │ ├── register.js
│ │ │ │ ├── login.js
│ │ │ │ ├── friends.js
│ │ │ │ ├── cam
│ │ │ │ │ ├── view.js
│ │ │ │ │ └── draw.js
│ │ │ │ └── main.js
│ │ │ ├── directives
│ │ │ │ ├── canvas.js
│ │ │ │ └── webcam.js
│ │ │ ├── core.js
│ │ │ └── providers
│ │ │ │ └── socket.js
│ │ │ ├── stylesheets
│ │ │ └── style.styl
│ │ │ └── index.html
│ ├── controllers
│ │ ├── socket.js
│ │ ├── session.js
│ │ ├── user.js
│ │ └── snap.js
│ ├── systems
│ │ ├── rediscon.js
│ │ ├── auth.js
│ │ ├── nocache.js
│ │ ├── imagepurge.js
│ │ └── pass.js
│ ├── package.json
│ ├── Web.Debug.config
│ ├── app.js
│ ├── Web.config
│ ├── models
│ │ └── User.js
│ ├── routes.js
│ └── RedSnap.njsproj
└── RedSnap.sln
├── .gitignore
├── LICENSE
├── .gitattributes
└── README.md
/RedSnap/RedSnap/bin/node.cmd:
--------------------------------------------------------------------------------
1 | node.exe %1 %2 %3
--------------------------------------------------------------------------------
/RedSnap/RedSnap/IISNode.yml:
--------------------------------------------------------------------------------
1 | loggingEnabled: true
2 | devErrorsEnabled: true
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/logout.html:
--------------------------------------------------------------------------------
1 |
You have been logged out
2 | You will be redirected shortly.
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/cam/snapcanvas.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/images/snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gaessaki/RedSnap/HEAD/RedSnap/RedSnap/public/images/snap.png
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gaessaki/RedSnap/HEAD/RedSnap/RedSnap/public/images/favicon.ico
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/images/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gaessaki/RedSnap/HEAD/RedSnap/RedSnap/public/images/spinner.gif
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/logout.html:
--------------------------------------------------------------------------------
1 | You have been logged out
2 | You will be redirected shortly.
--------------------------------------------------------------------------------
/RedSnap/RedSnap/controllers/socket.js:
--------------------------------------------------------------------------------
1 | module.exports = function (socket) {
2 |
3 | socket.on('new snap', function (data) {
4 |
5 | })
6 |
7 | }
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/cam/snapcanvas.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/stylesheets/style.styl:
--------------------------------------------------------------------------------
1 | body
2 | padding: 50px
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif
4 | a
5 | color: #00B7FF
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/images/snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gaessaki/RedSnap/HEAD/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/images/snap.png
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gaessaki/RedSnap/HEAD/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/images/favicon.ico
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/images/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gaessaki/RedSnap/HEAD/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/images/spinner.gif
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/Snap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('Snap', function ($resource) {
5 | return $resource('/api/snaps/');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/systems/rediscon.js:
--------------------------------------------------------------------------------
1 | var redis = require('redis');
2 |
3 | var config = require('../config.js');
4 |
5 | module.exports = redis.createClient({
6 | url: config.redisURL
7 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/Friend.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('Friend', function ($resource) {
5 | return $resource('/api/friends/');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/Session.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('Session', function ($resource) {
5 | return $resource('/auth/session/');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/SnapView.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('SnapView', function ($resource) {
5 | return $resource('/api/snaps/view');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/Snap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('Snap', function ($resource) {
5 | return $resource('/api/snaps/');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/Friend.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('Friend', function ($resource) {
5 | return $resource('/api/friends/');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/cam.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .controller('camController', function ($scope) {
3 | $scope.snapImage = {}
4 | $scope.snapWidth = {}
5 | $scope.snapHeight = {}
6 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/Session.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('Session', function ($resource) {
5 | return $resource('/auth/session/');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/SnapView.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('SnapView', function ($resource) {
5 | return $resource('/api/snaps/view');
6 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/systems/auth.js:
--------------------------------------------------------------------------------
1 | //passport middleware to ensure user is authenticated
2 | exports.ensureAuthenticated = function ensureAuthenticated(req, res, next) {
3 | if (req.isAuthenticated()) { return next(); }
4 | res.send(401);
5 | }
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/cam.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .controller('camController', function ($scope) {
3 | $scope.snapImage = {}
4 | $scope.snapWidth = {}
5 | $scope.snapHeight = {}
6 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/User.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('User', function ($resource) {
5 | return $resource('/auth/users/:id/', {},
6 | {
7 | 'update': {
8 | method: 'PUT'
9 | }
10 | });
11 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | var debug = require('debug')('RedSnap');
3 | var app = require('../app');
4 |
5 | app.set('port', process.env.PORT || 3000);
6 |
7 | var server = app.listen(app.get('port'), function() {
8 | debug('Express server listening on port ' + server.address().port);
9 | });
10 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/User.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap')
4 | .factory('User', function ($resource) {
5 | return $resource('/auth/users/:id/', {},
6 | {
7 | 'update': {
8 | method: 'PUT'
9 | }
10 | });
11 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/systems/nocache.js:
--------------------------------------------------------------------------------
1 |
2 | //Edge caches GET requests so we need to nocache whenver Angular GETS new data in regards to friends and the like
3 | module.exports = function nocache(req, res, next) {
4 | res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
5 | res.header('Expires', '-1');
6 | res.header('Pragma', 'no-cache');
7 | next();
8 | }
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/cam/view.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/logout.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('logoutController', function ($scope, $rootScope, $timeout, $state, Auth) {
4 | $scope.user = {}
5 | Auth.logout(function (err) {
6 | console.log(err);
7 | })
8 | $rootScope.loggedIn = false; //Solely used to toggle ng-show
9 | $timeout(
10 | function () {
11 | $state.go('login')
12 | }, 2500);
13 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/cam/view.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/logout.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('logoutController', function ($scope, $rootScope, $timeout, $state, Auth) {
4 | $scope.user = {}
5 | Auth.logout(function (err) {
6 | console.log(err);
7 | })
8 | $rootScope.loggedIn = false; //Solely used to toggle ng-show
9 | $timeout(
10 | function () {
11 | $state.go('login')
12 | }, 2500);
13 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{ snap.sender }}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{ snap.sender }}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/snapModal.html:
--------------------------------------------------------------------------------
1 |
9 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/snapModal.html:
--------------------------------------------------------------------------------
1 |
9 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/register.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('registerController', function ($location, $scope, Auth) {
4 | $scope.formData = {};
5 |
6 | $scope.register = function () {
7 | if ($scope.formData.username != undefined) {
8 | Auth.register($scope.formData, function (err) {
9 | $scope.errors= {}
10 |
11 | if (!err) {
12 | $location.path('/')
13 | }
14 | else {
15 | console.log(err)
16 |
17 | }
18 | });
19 |
20 | }
21 | }
22 |
23 | });
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/bin/ChangeConfig.ps1:
--------------------------------------------------------------------------------
1 | $configFile = $args[0]
2 |
3 | Write-Host "Adding iisnode section to config file '$configFile'"
4 | $config = New-Object System.Xml.XmlDocument
5 | $config.load($configFile)
6 | $xpath = $config.CreateNavigator()
7 | $parentElement = $xpath.SelectSingleNode("//configuration/configSections/sectionGroup[@name='system.webServer']")
8 | $iisnodeElement = $parentElement.SelectSingleNode("//section[@name='iisnode']")
9 | if ($iisnodeElement) {
10 | Write-Host "Removing existing iisnode section from config file '$configFile'"
11 | $iisnodeElement.DeleteSelf()
12 | }
13 |
14 | $parentElement.AppendChild("")
15 | $config.Save($configFile)
16 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/register.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('registerController', function ($location, $scope, Auth) {
4 | $scope.formData = {};
5 |
6 | $scope.register = function () {
7 | if ($scope.formData.username != undefined) {
8 | Auth.register($scope.formData, function (err) {
9 | $scope.errors= {}
10 |
11 | if (!err) {
12 | $location.path('/')
13 | }
14 | else {
15 | console.log(err)
16 |
17 | }
18 | });
19 |
20 | }
21 | }
22 |
23 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/systems/imagepurge.js:
--------------------------------------------------------------------------------
1 | //cron job that deletes photos that have all been played
2 | var CronJob = require('cron').CronJob;
3 | var redis = require('redis');
4 | var client = require('../systems/rediscon.js');
5 | var async = require('async')
6 |
7 | module.exports = new CronJob('00 00 4 * * 0-6', function () {
8 |
9 | client.lrange('deletion', 0, -1, function (err, reply) {
10 |
11 | async.each(reply, function (snap_id, cb) {
12 |
13 | //delete from filesystem
14 | //delete snap data from redis
15 | //call cronjob from app.js
16 |
17 | //Weird, I'm pretty sure I implemented this, but for some reason it's not on Github. Will have to check where the code went
18 |
19 | }, function (err) {
20 |
21 | })
22 |
23 | })
24 | });
25 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/directives/canvas.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .directive('snapcanvas', function () {
3 | return {
4 | templateUrl: 'views/cam/snapcanvas.html',
5 | replace: true,
6 | restrict: 'AE',
7 | scope: {
8 | config: '=conf'
9 | },
10 | link: function postLink($scope, elm) {
11 |
12 | var conf = $scope.$parent.conf;
13 | var c = document.createElement('canvas');
14 | var att = document.createAttribute("id");
15 | att.value = 'snapcan';
16 | c.setAttributeNode(att);
17 |
18 | c.width = conf.width;
19 | c.height = conf.height;
20 |
21 | var ctx = c.getContext('2d')
22 | ctx.putImageData(conf.imageData, 0, 0)
23 |
24 | angular.element(c).css("width", "100%")
25 |
26 | elm.find('div').append(c);
27 |
28 | }
29 |
30 | }
31 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/login.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .controller('loginController', function ($scope, $rootScope, Auth, $location) {
3 | $scope.user = {};
4 |
5 | $scope.login = function () {
6 | console.log('attempting log in')
7 | Auth.login($scope.user,
8 | function (err) {
9 | $scope.errors = [];
10 |
11 | if (!err) {
12 | $rootScope.loggedIn = true;
13 | $location.path('/');
14 | } else {
15 | angular.forEach(err.errors, function (error, key) {
16 | $scope.errors.push(error)
17 | })
18 | //angular.forEach(err.errors, function (error, field) {
19 | // form[field].$setValidity('mongoose', false);
20 | // $scope.errors[field] = error.type;
21 | //});
22 | }
23 | });
24 | };
25 | });
26 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RedSnap",
3 | "version": "0.2.2",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "description": "An open-source browser-based Snapchat clone",
9 | "author": {
10 | "name": "Mansib Rahman",
11 | "email": "mansib.rahman@outlook.com"
12 | },
13 | "dependencies": {
14 | "async": "1.5.2",
15 | "body-parser": "~1.8.1",
16 | "connect-redis": "*",
17 | "cookie-parser": "~1.3.3",
18 | "cron": "1.1.0",
19 | "crypto": "*",
20 | "debug": "~2.0.0",
21 | "express": "~4.9.0",
22 | "express-session": "*",
23 | "kerberos": "*",
24 | "mkdirp": "0.5.1",
25 | "mongoose": "^4.4.3",
26 | "morgan": "~1.3.0",
27 | "node-uuid": "*",
28 | "passport": "*",
29 | "passport-local": "*",
30 | "path": "*",
31 | "redis-session": "*",
32 | "serve-favicon": "~2.1.3",
33 | "socket.io": "*",
34 | "stylus": "0.42.3"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/directives/canvas.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .directive('snapcanvas', function () {
3 | return {
4 | templateUrl: 'views/cam/snapcanvas.html',
5 | replace: true,
6 | restrict: 'AE',
7 | scope: {
8 | config: '=conf'
9 | },
10 | link: function postLink($scope, elm) {
11 |
12 | var conf = $scope.$parent.conf;
13 | var c = document.createElement('canvas');
14 | var att = document.createAttribute("id");
15 | att.value = 'snapcan';
16 | c.setAttributeNode(att);
17 |
18 | c.width = conf.width;
19 | c.height = conf.height;
20 |
21 | var ctx = c.getContext('2d')
22 | ctx.putImageData(conf.imageData, 0, 0)
23 |
24 | angular.element(c).css("width", "100%")
25 |
26 | elm.find('div').append(c);
27 |
28 | }
29 |
30 | }
31 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/login.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .controller('loginController', function ($scope, $rootScope, Auth, $location) {
3 | $scope.user = {};
4 |
5 | $scope.login = function () {
6 | console.log('attempting log in')
7 | Auth.login($scope.user,
8 | function (err) {
9 | $scope.errors = [];
10 |
11 | if (!err) {
12 | $rootScope.loggedIn = true;
13 | $location.path('/');
14 | } else {
15 | angular.forEach(err.errors, function (error, key) {
16 | $scope.errors.push(error)
17 | })
18 | //angular.forEach(err.errors, function (error, field) {
19 | // form[field].$setValidity('mongoose', false);
20 | // $scope.errors[field] = error.type;
21 | //});
22 | }
23 | });
24 | };
25 | });
26 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/register.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/controllers/session.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var passport = require('passport');
4 |
5 | exports.session = function (req, res) {
6 | res.json(req.user.user_info);
7 | };
8 |
9 | exports.logout = function (req, res) {
10 | if (req.user) {
11 | req.logout();
12 | res.send(200);
13 | } else {
14 | res.send(400, "Not logged in");
15 | }
16 | };
17 |
18 | exports.login = function (req, res, next) {
19 | passport.authenticate('local', function (err, user, info) {
20 | var error = err || info;
21 | if (error) {
22 | console.log(error)
23 | return res.status(404).send(error);
24 | }
25 | req.logIn(user, function (err) {
26 | if (err) {
27 | console.log(error)
28 | res.status(404).send(error);
29 | }
30 | else {
31 | console.log(req.user)
32 | res.send(req.user.user_info);
33 | }
34 | });
35 | })(req, res, next);
36 | }
37 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/SnapService.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | angular.module('RedSnap')
4 | .factory('SnapService', function SnapService(Snap, SnapView) {
5 |
6 | return {
7 | sendSnap: function (snapData, callback) {
8 | var cb = callback || angular.noop;
9 | Snap.save({
10 | snap: snapData
11 | },
12 | function (err) {
13 | console.log(err.data);
14 | return cb(err.data);
15 | })
16 | },
17 | viewSnap: function (snapData, callback) {
18 | var cb = callback || angular.noop;
19 | SnapView.save({
20 | snapInfo: snapData
21 | }, function (snap) {
22 | return cb(snap);
23 | })
24 | },
25 | listSnaps: function (callback) {
26 | var cb = callback || angular.noop;
27 | Snap.query(function (snaps) {
28 | return cb(snaps);
29 | })
30 | }
31 | }
32 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/register.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "RedSnap", "RedSnap\RedSnap.njsproj", "{DA47B884-6324-463E-BF38-692F7F7A3F32}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {DA47B884-6324-463E-BF38-692F7F7A3F32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {DA47B884-6324-463E-BF38-692F7F7A3F32}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {DA47B884-6324-463E-BF38-692F7F7A3F32}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {DA47B884-6324-463E-BF38-692F7F7A3F32}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/SnapService.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | angular.module('RedSnap')
4 | .factory('SnapService', function SnapService(Snap, SnapView) {
5 |
6 | return {
7 | sendSnap: function (snapData, callback) {
8 | var cb = callback || angular.noop;
9 | Snap.save({
10 | snap: snapData
11 | },
12 | function (err) {
13 | console.log(err.data);
14 | return cb(err.data);
15 | })
16 | },
17 | viewSnap: function (snapData, callback) {
18 | var cb = callback || angular.noop;
19 | SnapView.save({
20 | snapInfo: snapData
21 | }, function (snap) {
22 | return cb(snap);
23 | })
24 | },
25 | listSnaps: function (callback) {
26 | var cb = callback || angular.noop;
27 | Snap.query(function (snaps) {
28 | return cb(snaps);
29 | })
30 | }
31 | }
32 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/friends.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('friendsController', function ($scope, $timeout, FriendService) {
4 | $scope.friends = {}
5 | $scope.potentialfriend = ""
6 | FriendService.listFriends(function (friends) {
7 | $scope.friends = friends;
8 | })
9 |
10 | $scope.befriend = function (friend) {
11 | $scope.potentialfriend = ""
12 | FriendService.addFriend(friend, function (err, friends) {
13 | if (err) {
14 | $scope.msg = err;
15 | }
16 | if (friends) {
17 | $scope.msg = "Friend request sent and/or friend added"
18 | $scope.friends = friends;
19 | $timeout(function () {
20 | $scope.msg = "";
21 | }, 3500)
22 | }
23 | })
24 |
25 | }
26 | $scope.unfriend = function (friend) {
27 | FriendService.removeFriend(friend, function (err, friends) {
28 | if (err) console.log(err)
29 | if (friends) $scope.friends = friends;
30 | })
31 | }
32 | })
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Mansib
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/friends.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('friendsController', function ($scope, $timeout, FriendService) {
4 | $scope.friends = {}
5 | $scope.potentialfriend = ""
6 | FriendService.listFriends(function (friends) {
7 | $scope.friends = friends;
8 | })
9 |
10 | $scope.befriend = function (friend) {
11 | $scope.potentialfriend = ""
12 | FriendService.addFriend(friend, function (err, friends) {
13 | if (err) {
14 | $scope.msg = err;
15 | }
16 | if (friends) {
17 | $scope.msg = "Friend request sent and/or friend added"
18 | $scope.friends = friends;
19 | $timeout(function () {
20 | $scope.msg = "";
21 | }, 3500)
22 | }
23 | })
24 |
25 | }
26 | $scope.unfriend = function (friend) {
27 | FriendService.removeFriend(friend, function (err, friends) {
28 | if (err) console.log(err)
29 | if (friends) $scope.friends = friends;
30 | })
31 | }
32 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/cam/view.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('camViewController', function ($scope, $state) {
4 |
5 | var _video = null;
6 | $scope.channel = {
7 | videoWidth: 640,
8 | videoHeight: 480
9 | };
10 |
11 | $scope.webcamError = false;
12 | $scope.onError = function (err) {
13 | $scope.$apply(function () {
14 | $scope.webcamError = err;
15 | })
16 | };
17 | $scope.onStream = function (stream) {
18 | _video = $scope.channel.video;
19 | };
20 | $scope.onSuccess = function () { };
21 |
22 | $scope.snap = function () {
23 | if (_video) {
24 | var idata = getVideoData(0, 0, _video.width, _video.height);
25 | $scope.$parent.snapImage = idata
26 | $scope.$parent.snapWidth = _video.width;
27 | $scope.$parent.snapHeight = _video.height;
28 | $state.go('cam.draw')
29 | }
30 | }
31 |
32 | var getVideoData = function getVideoData(x, y, w, h) {
33 | var c = document.createElement('canvas');
34 | c.width = w;
35 | c.height = h;
36 | var ctx = c.getContext('2d');
37 | ctx.drawImage(_video, 0, 0);
38 | return ctx.getImageData(x, y, w, h);
39 | }
40 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/cam/view.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('camViewController', function ($scope, $state) {
4 |
5 | var _video = null;
6 | $scope.channel = {
7 | videoWidth: 640,
8 | videoHeight: 480
9 | };
10 |
11 | $scope.webcamError = false;
12 | $scope.onError = function (err) {
13 | $scope.$apply(function () {
14 | $scope.webcamError = err;
15 | })
16 | };
17 | $scope.onStream = function (stream) {
18 | _video = $scope.channel.video;
19 | };
20 | $scope.onSuccess = function () { };
21 |
22 | $scope.snap = function () {
23 | if (_video) {
24 | var idata = getVideoData(0, 0, _video.width, _video.height);
25 | $scope.$parent.snapImage = idata
26 | $scope.$parent.snapWidth = _video.width;
27 | $scope.$parent.snapHeight = _video.height;
28 | $state.go('cam.draw')
29 | }
30 | }
31 |
32 | var getVideoData = function getVideoData(x, y, w, h) {
33 | var c = document.createElement('canvas');
34 | c.width = w;
35 | c.height = h;
36 | var ctx = c.getContext('2d');
37 | ctx.drawImage(_video, 0, 0);
38 | return ctx.getImageData(x, y, w, h);
39 | }
40 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/systems/pass.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose'),
2 | passport = require('passport'),
3 | LocalStrategy = require('passport-local').Strategy,
4 | User = mongoose.model('User');
5 |
6 | // Serialize sessions
7 | passport.serializeUser(function (user, done) {
8 | done(null, user.id);
9 | });
10 |
11 | passport.deserializeUser(function (id, done) {
12 | User.findOne({ _id: id }, function (err, user) {
13 | done(err, user);
14 | });
15 | });
16 |
17 | // Use local strategy
18 | passport.use(new LocalStrategy({
19 | usernameField: 'username',
20 | passwordField: 'password'
21 | },
22 | function (username, password, done) {
23 | console.log("attempting to find user")
24 | User.findOne({ username: username }, function (err, user) {
25 | if (err) {
26 | return done(err);
27 | }
28 | if (!user) {
29 | return done(null, false, {
30 | 'errors': {
31 | 'username': { type: 'Username is not registered.' }
32 | }
33 | });
34 | }
35 | if (!user.authenticate(password)) {
36 | return done(null, false, {
37 | 'errors': {
38 | 'password': { type: 'Password is incorrect.' }
39 | }
40 | });
41 | }
42 | console.log("found user")
43 | return done(null, user);
44 | });
45 | }
46 | ));
47 |
48 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/friends.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/friends.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/login.html:
--------------------------------------------------------------------------------
1 |
13 |
14 |
{{ error.type }}
15 |
16 |
17 |
RedSnap
18 |
An open-source web-based Snapchat clone. Built with node.js, express.js, angular, mongodb and redis.
19 |
20 |
21 | Historically, privacy was almost implicit, because it was hard to find and gather information. But in the digital world, whether it’s digital cameras or satellites or just what you click on, we need to have more explicit rules—not just for governments but for private companies. —Bill Gates
22 |
23 |
24 |
v 0.2.2 Code license MIT (c) 2016 —@gaessaki
25 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/login.html:
--------------------------------------------------------------------------------
1 |
13 |
14 |
{{ error.type }}
15 |
16 |
17 |
RedSnap
18 |
An open-source web-based Snapchat clone. Built with node.js, express.js, angular, mongodb and redis.
19 |
20 |
21 | Historically, privacy was almost implicit, because it was hard to find and gather information. But in the digital world, whether it’s digital cameras or satellites or just what you click on, we need to have more explicit rules—not just for governments but for private companies. —Bill Gates
22 |
23 |
24 |
v 0.2.2 Code license MIT (c) 2016 —@gaessaki
25 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/FriendService.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | angular.module('RedSnap')
4 | .factory('FriendService', function FriendService(Friend) {
5 |
6 | return {
7 | addFriend: function (friendName, callback) {
8 | var cb = callback || angular.noop;
9 | Friend.save({
10 | friend: friendName
11 | }, function () {
12 | Friend.get(function (friends) {
13 | return cb(null, friends);
14 | })
15 | },
16 | function (err) {
17 | console.log(err.data);
18 | Friend.get(function (friends) {
19 | return cb(err.data, friends);
20 | })
21 | return cb(err.data, null);
22 | })
23 | },
24 | removeFriend: function (friendName, callback) {
25 | var cb = callback || angular.noop;
26 | Friend.remove({
27 | friend: friendName
28 | }, function () {
29 | Friend.get(function (friends) {
30 | return cb(null, friends);
31 | })
32 | }),
33 | function (err) {
34 | console.log(err.data);
35 | Friend.get(function (friends) {
36 | return cb(err.data, friends);
37 | })
38 | return cb(err.data, null);
39 | }
40 | },
41 | listFriends: function (callback) {
42 | var cb = callback || angular.noop;
43 | Friend.get(function (friends) {
44 | return cb(friends);
45 | })
46 | }
47 | }
48 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/FriendService.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | angular.module('RedSnap')
4 | .factory('FriendService', function FriendService(Friend) {
5 |
6 | return {
7 | addFriend: function (friendName, callback) {
8 | var cb = callback || angular.noop;
9 | Friend.save({
10 | friend: friendName
11 | }, function () {
12 | Friend.get(function (friends) {
13 | return cb(null, friends);
14 | })
15 | },
16 | function (err) {
17 | console.log(err.data);
18 | Friend.get(function (friends) {
19 | return cb(err.data, friends);
20 | })
21 | return cb(err.data, null);
22 | })
23 | },
24 | removeFriend: function (friendName, callback) {
25 | var cb = callback || angular.noop;
26 | Friend.remove({
27 | friend: friendName
28 | }, function () {
29 | Friend.get(function (friends) {
30 | return cb(null, friends);
31 | })
32 | }),
33 | function (err) {
34 | console.log(err.data);
35 | Friend.get(function (friends) {
36 | return cb(err.data, friends);
37 | })
38 | return cb(err.data, null);
39 | }
40 | },
41 | listFriends: function (callback) {
42 | var cb = callback || angular.noop;
43 | Friend.get(function (friends) {
44 | return cb(friends);
45 | })
46 | }
47 | }
48 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/views/cam/draw.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Send To...
21 |
22 |
34 |
35 |
36 | Send
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/views/cam/draw.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Send To...
21 |
22 |
34 |
35 |
36 | Send
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/bin/setup_web.cmd:
--------------------------------------------------------------------------------
1 | @echo on
2 |
3 | cd /d "%~dp0"
4 |
5 | if "%EMULATED%"=="true" if DEFINED APPCMD goto emulator_setup
6 | if "%EMULATED%"== "true" exit /b 0
7 |
8 | echo Granting permissions for Network Service to the web root directory...
9 | icacls ..\ /grant "Network Service":(OI)(CI)W
10 | if %ERRORLEVEL% neq 0 goto error
11 | echo OK
12 |
13 | echo Configuring powershell permissions
14 | powershell -c "set-executionpolicy unrestricted"
15 |
16 | echo Downloading and installing runtime components
17 | powershell .\download.ps1 '%RUNTIMEURL%' '%RUNTIMEURLOVERRIDE%'
18 | if %ERRORLEVEL% neq 0 goto error
19 |
20 | echo SUCCESS
21 | exit /b 0
22 |
23 | :error
24 | echo FAILED
25 | exit /b -1
26 |
27 | :emulator_setup
28 | echo Running in emulator adding iisnode to application host config
29 | FOR /F "tokens=1,2 delims=/" %%a in ("%APPCMD%") DO set FN=%%a&set OPN=%%b
30 | if "%OPN%"=="%OPN:apphostconfig:=%" (
31 | echo "Could not parse appcmd '%appcmd% for configuration file, exiting"
32 | goto error
33 | )
34 |
35 | set IISNODE_BINARY_DIRECTORY=%programfiles(x86)%\iisnode-dev\release\x64
36 | set IISNODE_SCHEMA=%programfiles(x86)%\iisnode-dev\release\x64\iisnode_schema.xml
37 |
38 | if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto start
39 | set IISNODE_BINARY_DIRECTORY=%programfiles%\iisnode-dev\release\x86
40 | set IISNODE_SCHEMA=%programfiles%\iisnode-dev\release\x86\iisnode_schema_x86.xml
41 |
42 |
43 | :start
44 | set
45 |
46 | echo Using iisnode binaries location '%IISNODE_BINARY_DIRECTORY%'
47 | echo installing iisnode module using AppCMD alias %appcmd%
48 | %appcmd% install module /name:"iisnode" /image:"%IISNODE_BINARY_DIRECTORY%\iisnode.dll"
49 |
50 | set apphostconfigfile=%OPN:apphostconfig:=%
51 | powershell -c "set-executionpolicy unrestricted"
52 | powershell .\ChangeConfig.ps1 %apphostconfigfile%
53 | if %ERRORLEVEL% neq 0 goto error
54 |
55 | copy /y "%IISNODE_SCHEMA%" "%programfiles%\IIS Express\config\schema\iisnode_schema.xml"
56 | if %ERRORLEVEL% neq 0 goto error
57 | exit /b 0
58 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/Auth.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | angular.module('RedSnap')
4 | .factory('Auth', function Auth($rootScope, User, Session, $cookieStore) {
5 | $rootScope.currentUser = $cookieStore.get('user') || null;
6 | $cookieStore.remove('user');
7 |
8 | return {
9 |
10 | login: function (userData, callback) {
11 | var cb = callback || angular.noop;
12 | Session.save({
13 | username: userData.username,
14 | password: userData.password
15 | },
16 | function (user) {
17 | $rootScope.curentUser = user
18 | return cb();
19 | },
20 | function (err) {
21 | console.log(err.data)
22 | return cb(err.data);
23 | })
24 | },
25 | logout: function (callback) {
26 | var cb = callback || angular.noop;
27 | Session.delete(function (res) {
28 | $rootScope.curentUser = null;
29 | return cb();
30 | },
31 | function (err) {
32 | console.log(err.data);
33 | return cb(err.data);
34 | })
35 | },
36 | register: function (formData, callback) {
37 | var cb = callback || angular.noop;
38 | User.save(formData,
39 | function (user) {
40 | $rootScope.currentUser = user;
41 | return cb();
42 | },
43 | function (err) {
44 | console.log(err.data)
45 | return cb(err.data);
46 | })
47 | },
48 | currentUser: function () {
49 | Session.get(function (user) {
50 | $rootScope.currentUser = user;
51 | });
52 | },
53 | authenticate: function () {
54 | Session.get(function (user) {
55 | if (user) {
56 | $rootScope.loggedIn = true;
57 | return true;
58 | }
59 | else {
60 | $rootScope.loggedIn = false;
61 | return false;
62 | }
63 | });
64 | }
65 | }
66 | })
67 |
68 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/cam/draw.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('camDrawController', function ($scope, $state, FriendService, SnapService) {
4 |
5 | $scope.friends = {}
6 | $scope.sendFriends = []
7 | $scope.data = {
8 | availableOptions: [
9 | { value: '1', name: '1' },
10 | { value: '2', name: '2' },
11 | { value: '3', name: '3' },
12 | { value: '4', name: '4' },
13 | { value: '5', name: '5' },
14 | { value: '6', name: '6' },
15 | { value: '7', name: '7' },
16 | { value: '8', name: '8' },
17 | { value: '9', name: '9' },
18 | { value: '10', name: '10' }
19 | ],
20 | selectedOption: { value: '5', name: '5' } //This sets the default value of the select in the ui
21 | };
22 |
23 |
24 | FriendService.listFriends(function (friends) {
25 | $scope.friends = friends;
26 | })
27 |
28 | $scope.conf = {
29 | width: $scope.$parent.snapWidth,
30 | height: $scope.$parent.snapHeight,
31 | imageData: $scope.$parent.snapImage
32 | }
33 | $scope.checked = function (username, checkedval) {
34 | if (checkedval) {
35 | $scope.sendFriends.push(username)
36 | }
37 | else {
38 | if ($scope.sendFriends.indexOf(username) !== -1)
39 | $scope.sendFriends.splice($scope.sendFriends.indexOf(username), 1)
40 | }
41 | }
42 |
43 | $scope.sendSnap = function () {
44 |
45 | $scope.loading = true;
46 |
47 | var c = document.getElementById('snapcan')
48 | var dataURL = c.toDataURL();
49 | //get friends
50 | //get message
51 | //get time
52 |
53 | sendSnapObj = {
54 | img: dataURL,
55 | friends: $scope.sendFriends,
56 | time: $scope.data.selectedOption.value,
57 | text: $scope.loveMessage
58 | }
59 |
60 | SnapService.sendSnap(sendSnapObj, function (err) {
61 | if (!err) {
62 | $scope.loading = false;
63 | $state.go('main')
64 | }
65 | $scope.errors = err;
66 | })
67 | }
68 |
69 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/Auth.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | angular.module('RedSnap')
4 | .factory('Auth', function Auth($rootScope, User, Session, $cookieStore) {
5 | $rootScope.currentUser = $cookieStore.get('user') || null;
6 | $cookieStore.remove('user');
7 |
8 | return {
9 |
10 | login: function (userData, callback) {
11 | var cb = callback || angular.noop;
12 | Session.save({
13 | username: userData.username,
14 | password: userData.password
15 | },
16 | function (user) {
17 | $rootScope.curentUser = user
18 | return cb();
19 | },
20 | function (err) {
21 | console.log(err.data)
22 | return cb(err.data);
23 | })
24 | },
25 | logout: function (callback) {
26 | var cb = callback || angular.noop;
27 | Session.delete(function (res) {
28 | $rootScope.curentUser = null;
29 | return cb();
30 | },
31 | function (err) {
32 | console.log(err.data);
33 | return cb(err.data);
34 | })
35 | },
36 | register: function (formData, callback) {
37 | var cb = callback || angular.noop;
38 | User.save(formData,
39 | function (user) {
40 | $rootScope.currentUser = user;
41 | return cb();
42 | },
43 | function (err) {
44 | console.log(err.data)
45 | return cb(err.data);
46 | })
47 | },
48 | currentUser: function () {
49 | Session.get(function (user) {
50 | $rootScope.currentUser = user;
51 | });
52 | },
53 | authenticate: function () {
54 | Session.get(function (user) {
55 | if (user) {
56 | $rootScope.loggedIn = true;
57 | return true;
58 | }
59 | else {
60 | $rootScope.loggedIn = false;
61 | return false;
62 | }
63 | });
64 | }
65 | }
66 | })
67 |
68 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/cam/draw.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 |
3 | .controller('camDrawController', function ($scope, $state, FriendService, SnapService) {
4 |
5 | $scope.friends = {}
6 | $scope.sendFriends = []
7 | $scope.data = {
8 | availableOptions: [
9 | { value: '1', name: '1' },
10 | { value: '2', name: '2' },
11 | { value: '3', name: '3' },
12 | { value: '4', name: '4' },
13 | { value: '5', name: '5' },
14 | { value: '6', name: '6' },
15 | { value: '7', name: '7' },
16 | { value: '8', name: '8' },
17 | { value: '9', name: '9' },
18 | { value: '10', name: '10' }
19 | ],
20 | selectedOption: { value: '5', name: '5' } //This sets the default value of the select in the ui
21 | };
22 |
23 |
24 | FriendService.listFriends(function (friends) {
25 | $scope.friends = friends;
26 | })
27 |
28 | $scope.conf = {
29 | width: $scope.$parent.snapWidth,
30 | height: $scope.$parent.snapHeight,
31 | imageData: $scope.$parent.snapImage
32 | }
33 | $scope.checked = function (username, checkedval) {
34 | if (checkedval) {
35 | $scope.sendFriends.push(username)
36 | }
37 | else {
38 | if ($scope.sendFriends.indexOf(username) !== -1)
39 | $scope.sendFriends.splice($scope.sendFriends.indexOf(username), 1)
40 | }
41 | }
42 |
43 | $scope.sendSnap = function () {
44 |
45 | $scope.loading = true;
46 |
47 | var c = document.getElementById('snapcan')
48 | var dataURL = c.toDataURL();
49 | //get friends
50 | //get message
51 | //get time
52 |
53 | sendSnapObj = {
54 | img: dataURL,
55 | friends: $scope.sendFriends,
56 | time: $scope.data.selectedOption.value,
57 | text: $scope.loveMessage
58 | }
59 |
60 | SnapService.sendSnap(sendSnapObj, function (err) {
61 | if (!err) {
62 | $scope.loading = false;
63 | $state.go('main')
64 | }
65 | $scope.errors = err;
66 | })
67 | }
68 |
69 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/bin/download.ps1:
--------------------------------------------------------------------------------
1 | $runtimeUrl = $args[0]
2 | $overrideUrl = $args[1]
3 | $current = [string] (Get-Location -PSProvider FileSystem)
4 | $client = New-Object System.Net.WebClient
5 |
6 | function downloadWithRetry {
7 | param([string]$url, [string]$dest, [int]$retry)
8 | Write-Host
9 | Write-Host "Attempt: $retry"
10 | Write-Host
11 | trap {
12 | Write-Host $_.Exception.ToString()
13 | if ($retry -lt 5) {
14 | $retry=$retry+1
15 | Write-Host
16 | Write-Host "Waiting 5 seconds and retrying"
17 | Write-Host
18 | Start-Sleep -s 5
19 | downloadWithRetry $url $dest $retry $client
20 | }
21 | else {
22 | Write-Host "Download failed"
23 | throw "Max number of retries downloading [5] exceeded"
24 | }
25 | }
26 | $client.downloadfile($url, $dest)
27 | }
28 |
29 | function download($url, $dest) {
30 | Write-Host "Downloading $url"
31 | downloadWithRetry $url $dest 1
32 | }
33 |
34 | function copyOnVerify($file, $output) {
35 | Write-Host "Verifying $file"
36 | $verify = Get-AuthenticodeSignature $file
37 | Out-Host -InputObject $verify
38 | if ($verify.Status -ne "Valid") {
39 | throw "Invalid signature for runtime package $file"
40 | }
41 | else {
42 | mv $file $output
43 | }
44 | }
45 |
46 | if ($overrideUrl) {
47 | Write-Host "Using override url: $overrideUrl"
48 | $url = $overrideUrl
49 | }
50 | else {
51 | $url = $runtimeUrl
52 | }
53 |
54 | foreach($singleUrl in $url -split ";")
55 | {
56 | $suffix = Get-Random
57 | $downloaddir = $current + "\sandbox" + $suffix
58 | mkdir $downloaddir
59 | $dest = $downloaddir + "\sandbox.exe"
60 | download $singleUrl $dest
61 | $final = $downloaddir + "\runtime.exe"
62 | copyOnVerify $dest $final
63 | if (Test-Path -LiteralPath $final)
64 | {
65 | cd $downloaddir
66 | if ($host.Version.Major -eq 3)
67 | {
68 | .\runtime.exe -y | Out-Null
69 | .\setup.cmd
70 | }
71 | else
72 | {
73 | Start-Process -FilePath $final -ArgumentList -y -Wait
74 | $cmd = $downloaddir + "\setup.cmd"
75 | Start-Process -FilePath $cmd -Wait
76 | }
77 | }
78 | else
79 | {
80 | throw "Unable to verify package"
81 | }
82 | cd $current
83 | if (Test-Path -LiteralPath $downloaddir)
84 | {
85 | Remove-Item -LiteralPath $downloaddir -Force -Recurse
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/core.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap', ['ui.router', 'ui.bootstrap', 'ngCookies', 'ngSanitize', 'ngResource', 'ngAnimate', 'webcam', 'http-auth-interceptor'])
4 | .config(function ($stateProvider, $urlRouterProvider) {
5 |
6 | $urlRouterProvider.otherwise('/');
7 |
8 | $stateProvider
9 | .state('main', {
10 | url: '/',
11 | templateUrl: '/views/main.html',
12 | controller: 'mainController',
13 | resolve: {
14 | authenticate: function (Auth) {
15 | return Auth.authenticate();
16 | }
17 | }
18 | })
19 | .state('cam', {
20 | abstract: true,
21 | url: '/cam',
22 | template: ' ',
23 | controller: 'camController',
24 | resolve: {
25 | authenticate: function (Auth) {
26 | return Auth.authenticate();
27 | }
28 | }
29 | })
30 | .state('cam.view', {
31 | url: '/view',
32 | templateUrl: '/views/cam/view.html',
33 | controller: 'camViewController'
34 | })
35 | .state('cam.draw', {
36 | url: '/draw',
37 | templateUrl: '/views/cam/draw.html',
38 | controller: 'camDrawController'
39 | })
40 | .state('friends', {
41 | url: '/friends',
42 | templateUrl: '/views/friends.html',
43 | controller: 'friendsController',
44 | resolve: {
45 | authenticate: function (Auth) {
46 | return Auth.authenticate();
47 | }
48 | }
49 | })
50 | .state('login', {
51 | url: '/login',
52 | templateUrl: '/views/login.html',
53 | controller: 'loginController'
54 | })
55 | .state('logout', {
56 | url: '/logout',
57 | templateUrl: '/views/logout.html',
58 | controller: 'logoutController'
59 | })
60 | .state('register', {
61 | url: '/register',
62 | templateUrl: '/views/register.html',
63 | controller: 'registerController'
64 | })
65 | })
66 | .run(function ($rootScope, $state, $location, Auth) {
67 | $rootScope.$watch('currentUser', function (currentUser) {
68 | if (!$rootScope.currentUser && !$state.includes('login')) {
69 | Auth.currentUser();
70 | }
71 | });
72 | //On 401, redirect to login, implements http-auth-interceptor
73 | $rootScope.$on('event:auth-loginRequired', function () {
74 | $rootScope.loggedIn = false;
75 | $location.path('/login')
76 | return false;
77 | })
78 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/core.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('RedSnap', ['ui.router', 'ui.bootstrap', 'ngCookies', 'ngSanitize', 'ngResource', 'ngAnimate', 'webcam', 'http-auth-interceptor'])
4 | .config(function ($stateProvider, $urlRouterProvider) {
5 |
6 | $urlRouterProvider.otherwise('/');
7 |
8 | $stateProvider
9 | .state('main', {
10 | url: '/',
11 | templateUrl: '/views/main.html',
12 | controller: 'mainController',
13 | resolve: {
14 | authenticate: function (Auth) {
15 | return Auth.authenticate();
16 | }
17 | }
18 | })
19 | .state('cam', {
20 | abstract: true,
21 | url: '/cam',
22 | template: ' ',
23 | controller: 'camController',
24 | resolve: {
25 | authenticate: function (Auth) {
26 | return Auth.authenticate();
27 | }
28 | }
29 | })
30 | .state('cam.view', {
31 | url: '/view',
32 | templateUrl: '/views/cam/view.html',
33 | controller: 'camViewController'
34 | })
35 | .state('cam.draw', {
36 | url: '/draw',
37 | templateUrl: '/views/cam/draw.html',
38 | controller: 'camDrawController'
39 | })
40 | .state('friends', {
41 | url: '/friends',
42 | templateUrl: '/views/friends.html',
43 | controller: 'friendsController',
44 | resolve: {
45 | authenticate: function (Auth) {
46 | return Auth.authenticate();
47 | }
48 | }
49 | })
50 | .state('login', {
51 | url: '/login',
52 | templateUrl: '/views/login.html',
53 | controller: 'loginController'
54 | })
55 | .state('logout', {
56 | url: '/logout',
57 | templateUrl: '/views/logout.html',
58 | controller: 'logoutController'
59 | })
60 | .state('register', {
61 | url: '/register',
62 | templateUrl: '/views/register.html',
63 | controller: 'registerController'
64 | })
65 | })
66 | .run(function ($rootScope, $state, $location, Auth) {
67 | $rootScope.$watch('currentUser', function (currentUser) {
68 | if (!$rootScope.currentUser && !$state.includes('login')) {
69 | Auth.currentUser();
70 | }
71 | });
72 | //On 401, redirect to login, implements http-auth-interceptor
73 | $rootScope.$on('event:auth-loginRequired', function () {
74 | $rootScope.loggedIn = false;
75 | $location.path('/login')
76 | return false;
77 | })
78 | });
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/controllers/main.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .controller('mainController', function ($scope, $interval, $uibModal, SnapService) {
3 |
4 | $scope.snaps = {};
5 | $scope.snapData = {}
6 | var time = 0;
7 |
8 |
9 | SnapService.listSnaps(function (snaps) {
10 | $scope.snaps = snaps;
11 | })
12 |
13 | $scope.open = function (snapRequestData) {
14 |
15 | SnapService.viewSnap(snapRequestData, function (snap) {
16 | $scope.snapData = snap
17 | time = $scope.snapData.time;
18 |
19 | var modalInstance = $uibModal.open({
20 | animation: $scope.animationsEnabled,
21 | templateUrl: '../../views/snapModal.html',
22 | controller: 'snapModalController',
23 | keyboard: true,
24 | scope: $scope
25 | })
26 |
27 | SnapService.listSnaps(function (snaps) {
28 | $scope.snaps = snaps;
29 | })
30 |
31 | modalInstance.result.then(function () {
32 | if (angular.isDefined(promise)) {
33 | $interval.cancel(promise)
34 | }
35 | }, function () {
36 | if (angular.isDefined(promise)) {
37 | $interval.cancel(promise)
38 | }
39 | });
40 | })
41 |
42 | }
43 |
44 | var fetcher = $interval(function () {
45 | SnapService.listSnaps(function (snaps) {
46 | $scope.snaps = snaps;
47 | })
48 | }, 90000)
49 |
50 | $scope.$on('$destroy', function () {
51 | $interval.cancel(fetcher);
52 | })
53 |
54 | $scope.start = function (modInst) {
55 | promise = $interval(function () {
56 | $scope.snapData.time--;
57 | if ($scope.snapData.time < 1) {
58 | modInst.close();
59 | }
60 | }, 1000, time)
61 | }
62 |
63 | })
64 |
65 | angular.module('RedSnap')
66 | .controller('snapModalController', function ($scope, $interval, $timeout, $uibModalInstance) {
67 |
68 | $timeout(function () { //hack to render DOM before controller logic. Will move into directive
69 | var img = new Image;
70 |
71 | var c = document.getElementById('bg-can')
72 | c.width = 640;
73 | c.height = 480;
74 | var ctx = c.getContext('2d');
75 | img.onload = function () {
76 | ctx.drawImage(img, 0, 0);
77 | }
78 | img.src = $scope.snapData.imgData;
79 |
80 | $scope.start($uibModalInstance);
81 | }, 0)
82 |
83 |
84 |
85 |
86 | })
--------------------------------------------------------------------------------
/RedSnap/RedSnap/app.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var favicon = require('serve-favicon');
4 | var logger = require('morgan');
5 | var cookieParser = require('cookie-parser');
6 | var bodyParser = require('body-parser');
7 | var session = require('express-session');
8 | var RedisStore = require('connect-redis') (session);
9 |
10 | var config = require('./config.js');
11 | var mongoose = require('mongoose');
12 |
13 | var client = require('./systems/rediscon.js')
14 |
15 | client.on('connect', function () {
16 | console.log('Connection to Redis Server established');
17 | });
18 |
19 | global.appRoot = path.resolve(__dirname);
20 |
21 | var app = express();
22 |
23 | var passport = require('passport');
24 | var User = require('./models/User');
25 |
26 | //var io = require('socket.io').listen(app);
27 | //var socket = require('./controllers/socket');
28 |
29 | mongoose.connect(config.mongoURL, config.mongoOptions, function (err, res) {
30 | if (err) console.log("error connecting to db " + err)
31 | else console.log('Connection to MongoDB instance established')
32 | });
33 |
34 | var pass = require('./systems/pass')
35 |
36 | app.use(favicon(__dirname + '/public/images/favicon.ico'));
37 | app.use(logger('dev'));
38 | app.use(bodyParser.json({limit: '2048kb' }));
39 | app.use(bodyParser.urlencoded({ extended: false }));
40 | app.use(session({
41 | secret: 'McGillCollegeAveXs',
42 | store: new RedisStore({ client: client, ttl: 260 }),
43 | saveUninitialized: false,
44 | resave: false
45 | }))
46 | app.use(cookieParser());
47 | app.use(require('stylus').middleware(path.join(__dirname, 'public')));
48 | app.use(express.static(path.join(__dirname, 'public')));
49 |
50 | app.use(passport.initialize());
51 | app.use(passport.session());
52 |
53 | require('./routes.js')(app);
54 |
55 | // catch 404 and forward to error handler
56 | app.use(function (req, res, next) {
57 | var err = new Error('Not Found');
58 | err.status = 404;
59 | next(err);
60 | });
61 |
62 | // error handlers
63 |
64 | // development error handler
65 | // will print stacktrace
66 | if (app.get('env') === 'development') {
67 | app.use(function (err, req, res, next) {
68 | res.status(err.status || 500);
69 | res.render('error', {
70 | message: err.message,
71 | error: err
72 | });
73 | });
74 | }
75 |
76 | // production error handler
77 | // no stacktraces leaked to user
78 | app.use(function (err, req, res, next) {
79 | res.status(err.status || 500);
80 | res.render('error', {
81 | message: err.message,
82 | error: {}
83 | });
84 | });
85 |
86 | //io.sockets.on('connection', socket)
87 |
88 | module.exports = app;
89 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/controllers/main.js:
--------------------------------------------------------------------------------
1 | angular.module('RedSnap')
2 | .controller('mainController', function ($scope, $interval, $uibModal, SnapService) {
3 |
4 | $scope.snaps = {};
5 | $scope.snapData = {}
6 | var time = 0;
7 |
8 |
9 | SnapService.listSnaps(function (snaps) {
10 | $scope.snaps = snaps;
11 | })
12 |
13 | $scope.open = function (snapRequestData) {
14 |
15 | SnapService.viewSnap(snapRequestData, function (snap) {
16 | $scope.snapData = snap
17 | time = $scope.snapData.time;
18 |
19 | var modalInstance = $uibModal.open({
20 | animation: $scope.animationsEnabled,
21 | templateUrl: '../../views/snapModal.html',
22 | controller: 'snapModalController',
23 | keyboard: true,
24 | scope: $scope
25 | })
26 |
27 | SnapService.listSnaps(function (snaps) {
28 | $scope.snaps = snaps;
29 | })
30 |
31 | modalInstance.result.then(function () {
32 | if (angular.isDefined(promise)) {
33 | $interval.cancel(promise)
34 | }
35 | }, function () {
36 | if (angular.isDefined(promise)) {
37 | $interval.cancel(promise)
38 | }
39 | });
40 | })
41 |
42 | }
43 |
44 | var fetcher = $interval(function () {
45 | SnapService.listSnaps(function (snaps) {
46 | $scope.snaps = snaps;
47 | })
48 | }, 90000)
49 |
50 | $scope.$on('$destroy', function () {
51 | $interval.cancel(fetcher);
52 | })
53 |
54 | $scope.start = function (modInst) {
55 | promise = $interval(function () {
56 | $scope.snapData.time--;
57 | if ($scope.snapData.time < 1) {
58 | modInst.close();
59 | }
60 | }, 1000, time)
61 | }
62 |
63 | })
64 |
65 | angular.module('RedSnap')
66 | .controller('snapModalController', function ($scope, $interval, $timeout, $uibModalInstance) {
67 |
68 | $timeout(function () { //hack to render DOM before controller logic. Will move into directive
69 | var img = new Image;
70 |
71 | var c = document.getElementById('bg-can')
72 | c.width = 640;
73 | c.height = 480;
74 | var ctx = c.getContext('2d');
75 | img.onload = function () {
76 | ctx.drawImage(img, 0, 0);
77 | }
78 | img.src = $scope.snapData.imgData;
79 |
80 | $scope.start($uibModalInstance);
81 | }, 0)
82 |
83 |
84 |
85 |
86 | })
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/stylesheets/style.styl:
--------------------------------------------------------------------------------
1 | body
2 | padding: 50px
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif
4 | a
5 | color: #00B7FF
6 | .navbar-default {
7 | background-color: #cb1c0a;
8 | border-color: #911205;
9 | }
10 | .navbar-default .navbar-brand {
11 | color: #ecf0f1;
12 | }
13 | .navbar-default .navbar-brand:hover,
14 | .navbar-default .navbar-brand:focus {
15 | color: #ffbbbc;
16 | }
17 | .navbar-default .navbar-text {
18 | color: #ecf0f1;
19 | }
20 | .navbar-default .navbar-nav > li > a {
21 | color: #ecf0f1;
22 | }
23 | .navbar-default .navbar-nav > li > a:hover,
24 | .navbar-default .navbar-nav > li > a:focus {
25 | color: #ffbbbc;
26 | }
27 | .navbar-default .navbar-nav > .active > a,
28 | .navbar-default .navbar-nav > .active > a:hover,
29 | .navbar-default .navbar-nav > .active > a:focus {
30 | color: #ffbbbc;
31 | background-color: #911205;
32 | }
33 | .navbar-default .navbar-nav > .open > a,
34 | .navbar-default .navbar-nav > .open > a:hover,
35 | .navbar-default .navbar-nav > .open > a:focus {
36 | color: #ffbbbc;
37 | background-color: #911205;
38 | }
39 | .navbar-default .navbar-toggle {
40 | border-color: #911205;
41 | }
42 | .navbar-default .navbar-toggle:hover,
43 | .navbar-default .navbar-toggle:focus {
44 | background-color: #911205;
45 | }
46 | .navbar-default .navbar-toggle .icon-bar {
47 | background-color: #ecf0f1;
48 | }
49 | .navbar-default .navbar-collapse,
50 | .navbar-default .navbar-form {
51 | border-color: #ecf0f1;
52 | }
53 | .navbar-default .navbar-link {
54 | color: #ecf0f1;
55 | }
56 | .navbar-default .navbar-link:hover {
57 | color: #ffbbbc;
58 | }
59 |
60 | @media (max-width: 767px) {
61 | .navbar-default .navbar-nav .open .dropdown-menu > li > a {
62 | color: #ecf0f1;
63 | }
64 | .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
65 | .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
66 | color: #ffbbbc;
67 | }
68 | .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
69 | .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
70 | .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
71 | color: #ffbbbc;
72 | background-color: #911205;
73 | }
74 | }
75 | .cam-box
76 | text-align: center
77 | margin-top: 10px
78 | .webcam-live
79 | width: 85%
80 | height: auto
81 | z-index: -1
82 | #snapButton
83 | z-index: 100
84 | position: relative
85 | display: block
86 | margin: -6.5% auto
87 | width: 40%
88 | background: rgba(60, 60, 60, 0.4)
89 | #snapButton:active
90 | background: rgba(255, 100, 100, 0.8)
91 | .form-signin-heading
92 | color: white
93 | #login-well
94 | background-color: #cb1c0a
95 | max-width: 320px;
96 | margin: 20px auto;
97 | border-color: #911205;
98 | #login-text
99 | max-width: 420px;
100 | margin: 10px auto;
101 | #login-title
102 | margin-top: 0
103 | .snap-img
104 | width: 640px
105 | height: 480px
106 | background-image:url('../images/snap.png')
107 | margin: 10px auto
108 | #bg-can
109 | position: absolute
110 | z-index: 1100
111 | .modal-content
112 | min-width: 680px
113 |
114 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
35 |
36 |
37 |
38 |
40 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
74 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 | a {
6 | color: #00b7ff;
7 | }
8 | .navbar-default {
9 | background-color: #cb1c0a;
10 | border-color: #911205;
11 | }
12 | .navbar-default .navbar-brand {
13 | color: #ecf0f1;
14 | }
15 | .navbar-default .navbar-brand:hover,
16 | .navbar-default .navbar-brand:focus {
17 | color: #ffbbbc;
18 | }
19 | .navbar-default .navbar-text {
20 | color: #ecf0f1;
21 | }
22 | .navbar-default .navbar-nav > li > a {
23 | color: #ecf0f1;
24 | }
25 | .navbar-default .navbar-nav > li > a:hover,
26 | .navbar-default .navbar-nav > li > a:focus {
27 | color: #ffbbbc;
28 | }
29 | .navbar-default .navbar-nav > .active > a,
30 | .navbar-default .navbar-nav > .active > a:hover,
31 | .navbar-default .navbar-nav > .active > a:focus {
32 | color: #ffbbbc;
33 | background-color: #911205;
34 | }
35 | .navbar-default .navbar-nav > .open > a,
36 | .navbar-default .navbar-nav > .open > a:hover,
37 | .navbar-default .navbar-nav > .open > a:focus {
38 | color: #ffbbbc;
39 | background-color: #911205;
40 | }
41 | .navbar-default .navbar-toggle {
42 | border-color: #911205;
43 | }
44 | .navbar-default .navbar-toggle:hover,
45 | .navbar-default .navbar-toggle:focus {
46 | background-color: #911205;
47 | }
48 | .navbar-default .navbar-toggle .icon-bar {
49 | background-color: #ecf0f1;
50 | }
51 | .navbar-default .navbar-collapse,
52 | .navbar-default .navbar-form {
53 | border-color: #ecf0f1;
54 | }
55 | .navbar-default .navbar-link {
56 | color: #ecf0f1;
57 | }
58 | .navbar-default .navbar-link:hover {
59 | color: #ffbbbc;
60 | }
61 | @media (max-width: 767px) {
62 | .navbar-default .navbar-nav .open .dropdown-menu > li > a {
63 | color: #ecf0f1;
64 | }
65 | .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
66 | .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
67 | color: #ffbbbc;
68 | }
69 | .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
70 | .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
71 | .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
72 | color: #ffbbbc;
73 | background-color: #911205;
74 | }
75 | }
76 | .cam-box {
77 | text-align: center;
78 | margin-top: 10px;
79 | }
80 | .webcam-live {
81 | width: 85%;
82 | height: auto;
83 | z-index: -1;
84 | }
85 | #snapButton {
86 | z-index: 100;
87 | position: relative;
88 | display: block;
89 | margin: -6.5% auto;
90 | width: 40%;
91 | background: rgba(60,60,60,0.4);
92 | }
93 | #snapButton:active {
94 | background: rgba(255,100,100,0.8);
95 | }
96 | .form-signin-heading {
97 | color: #fff;
98 | }
99 | #login-well {
100 | background-color: #cb1c0a;
101 | max-width: 320px;
102 | margin: 20px auto;
103 | border-color: #911205;
104 | }
105 | #login-text {
106 | max-width: 420px;
107 | margin: 10px auto;
108 | }
109 | #login-title {
110 | margin-top: 0;
111 | }
112 | .snap-img {
113 | width: 640px;
114 | height: 480px;
115 | background-image: url("../images/snap.png");
116 | margin: 10px auto;
117 | }
118 | #bg-can {
119 | position: absolute;
120 | z-index: 1100;
121 | }
122 | .modal-content {
123 | min-width: 680px;
124 | }
125 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/models/User.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | var Schema = mongoose.Schema;
3 | var crypto = require('crypto');
4 |
5 | var UserSchema = new Schema({
6 | username: {
7 | type: String, required: true, unique: true
8 | },
9 | email: {
10 | type: String, required: true, unique: true
11 | },
12 | date_joined: {
13 | type: Date, required: true, default: Date
14 | },
15 | snap_count: {
16 | sent: { type: Number, default: 0 },
17 | received: { type: Number, default: 0 }
18 | },
19 | friends: {
20 | requested: [{username: String}],
21 | current: [{username: String}]
22 | },
23 | hashedPassword: String,
24 | salt: String
25 |
26 | });
27 |
28 | UserSchema.virtual('password')
29 | .set(function (password) {
30 | this._password = password;
31 | this.salt = this.makeSalt();
32 | this.hashedPassword = this.encryptPassword(password);
33 | })
34 | .get(function () {
35 | return this._password;
36 | });
37 |
38 |
39 | UserSchema
40 | .virtual('user_info')
41 | .get(function () {
42 | return { '_id': this._id, 'username': this.username, 'email': this.email, 'snap_count': this.snap_count, 'friends': this.friends };
43 | });
44 |
45 | var validatePresenceOf = function (value) {
46 | return value && value.length;
47 | };
48 |
49 | UserSchema.path('email').validate(function (email) {
50 | var emailRegex = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
51 | return emailRegex.test(email);
52 | }, 'The specified email is invalid.');
53 |
54 | UserSchema.path('email').validate(function (value, respond) {
55 | mongoose.models["User"].findOne({ email: value }, function (err, user) {
56 | if (err) throw err;
57 | if (user) return respond(false);
58 | respond(true);
59 | });
60 | }, 'The specified email address is already in use.');
61 |
62 | UserSchema.path('username').validate(function (value, respond) {
63 | mongoose.models["User"].findOne({ username: value }, function (err, user) {
64 | if (err) throw err;
65 | if (user) return respond(false);
66 | respond(true);
67 | });
68 | }, 'The specified username is already in use.');
69 |
70 | UserSchema.pre('save', function (next) {
71 | if (!this.isNew) {
72 | return next();
73 | }
74 |
75 | if (!validatePresenceOf(this.password)) {
76 | next(new Error('Invalid password'));
77 | }
78 | else {
79 | next();
80 | }
81 | });
82 |
83 |
84 | UserSchema.methods = {
85 |
86 | /**
87 | * Authenticate - check if the passwords are the same
88 | */
89 |
90 | authenticate: function (plainText) {
91 | return this.encryptPassword(plainText) === this.hashedPassword;
92 | },
93 |
94 | /**
95 | * Make salt
96 | */
97 |
98 | makeSalt: function () {
99 | return crypto.randomBytes(16).toString('base64');
100 | },
101 |
102 | /**
103 | * Encrypt password
104 | */
105 |
106 | encryptPassword: function (password) {
107 | if (!password || !this.salt) return '';
108 | var salt = new Buffer(this.salt, 'base64');
109 | return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');
110 | }
111 | };
112 |
113 | mongoose.model('User', UserSchema);
114 |
115 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/routes.js:
--------------------------------------------------------------------------------
1 | var passport = require('passport');
2 | var auth = require('./systems/auth');
3 | var nocache = require('./systems/nocache.js');
4 |
5 | module.exports = function (app) {
6 | // User Routes
7 | var session = require('./controllers/session');
8 | var users = require('./controllers/user');
9 | var snap = require('./controllers/snap');
10 |
11 | app.get('/api/snaps', nocache, auth.ensureAuthenticated, snap.receivesnaps);
12 | app.post('/api/snaps', auth.ensureAuthenticated, snap.sendsnaps);
13 |
14 | app.post('/api/snaps/view', auth.ensureAuthenticated, snap.viewsnap);
15 |
16 | app.get('/api/friends', nocache, auth.ensureAuthenticated, users.friends);
17 | app.post('/api/friends', auth.ensureAuthenticated, users.friend);
18 | app.delete('/api/friends', auth.ensureAuthenticated, users.unfriend);
19 |
20 | app.post('/auth/users', users.register);
21 |
22 | app.get('/auth/session', auth.ensureAuthenticated, session.session);
23 | app.post('/auth/session', session.login);
24 | app.delete('/auth/session', session.logout);
25 |
26 | // Angular Routes
27 | //app.get('/views/main', auth.ensureAuthenticated, session.session, function (req, res) {
28 | // res.send('views/main.html')
29 | //})
30 | //app.get('/views/*', function (req, res) {
31 | // var requestedView = path.join('./', req.url);
32 | // res.send(requestedView);
33 | //});
34 |
35 | app.get('/*', function (req, res) {
36 | if (req.user) {
37 | res.cookie('user', JSON.stringify(req.user));
38 | }
39 |
40 | res.send('index.html');
41 | });
42 |
43 | }
44 |
45 | //module.exports = function (app) {
46 |
47 | // app.get('api/account', auth.ensureAuthenticated, function (req, res) {
48 | // if (req.isAuthenticated()) {
49 | // res.json(req.user);
50 | // }
51 | // res.send(401);
52 | // });
53 |
54 | // app.post('api/account/login',
55 | // passport.authenticate('local', function (req, res) {
56 | // User.find({username: req.body.username}, function (err, user) {
57 | // if (err) res.send(err);
58 | // var identity = {
59 | // id: user._id,
60 | // username: user.username,
61 | // email: user.email,
62 | // friends: user.friends,
63 | // snap_count: user.snap_count
64 | // }
65 | // res.send(identity);
66 | // })
67 | // }));
68 |
69 |
70 |
71 | // app.post('api/account/register', function (req, res) {
72 | // User.register(new User({ username: req.body.username, email: req.body.email }), req.body.password, function (err) {
73 | // if (err) console.log('error during registration')
74 | // });
75 | // User.find({ username: req.body.username }, function (err, user) {
76 | // var identity = {
77 | // id: user._id,
78 | // username: user.username,
79 | // email: user.email,
80 | // friends: user.friends,
81 | // snap_count: user.snap_count
82 | // }
83 | // res.send(identity);
84 | // })
85 | // });
86 | // app.get('api/account/logout', function (req, res) {
87 | // req.logout();
88 | // res.status(200);
89 | // })
90 | // //app.get('/views/*', function (req, res) {
91 | // // var view = path.join('./', req.url);
92 | // // console.log(view)
93 | // // res.sendfile(view)
94 | // //})
95 | // //app.get('/', function (req, res) {
96 | // // if (req.user) {
97 | // // res.cookie('user', JSON.stringify(user));
98 | // // }
99 | // // res.sendfile(index.html)
100 | // //})
101 | //}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### RedSnap
2 | An open-source web-based Snapchat clone. Built with node.js, express.js, angular, mongodb and redis.
3 |
4 | *Historically, privacy was almost implicit, because it was hard to find and gather information. But in the digital world, whether it’s digital cameras or satellites or just what you click on, we need to have more explicit rules—not just for governments but for private companies. —Bill Gates*
5 |
6 | Works in the latest versions of Edge, Firefox and Chrome (use https to enable webcam). Works to some degree on Android Chrome. Please read the [notice] (https://github.com/gaessaki/RedSnap/blob/master/README.md#notice) before trying the site out. As the app was built as an MVP over the weekend, the code is by no means an indicator of best practices. There are many vulnerabilities that I am aware of in the code and I am sure you will find more (Please contribute fixes if you can). DEMO: https://myhack.ca.
7 |
8 | #### Why did I build this?
9 |
10 | My primary intention was to practice my web development skills as I come from a .NET and Android background. The more I got into it however, the more I saw the importance and the need of an open-source alternative to Snapchat. By no means am I anti-Snapchat (I'll still probably use it every day for the time being), but the incentives are evident:
11 |
12 | * As a non-profit open source project, no complicitness in comprimising data to advertisters or the gov't
13 | * Project development not geared towards monetization (e.g. ads, blocking 3rd party clients)
14 | * Clients can be built for any device (Yay Windows Phone! Or perhaps integration with a digital camera, drone, etc.?)
15 | * Users can host private RedSnap servers that only members of their community can join (e.g. family, company, school club)
16 | * Customize your own installation of RedSnap however you want. Change snapping rules, colour schemes, make your own filter, etc.
17 | * An example of a complete node.js/angular project for newbies to learn from
18 |
19 | The node.js app can expose its API and thus iOS, Android, Windows Phone, Raspberry Pi, etc. clients are all possible. Please email me at mansib.rahman@outlook.com if you are interested in contributing.
20 |
21 | ## Notice
22 |
23 | As it stands, RedSnap is WIP and thus I can make no guarantee of security, privacy or functionality. Refrain from submitting personally indentifiable information or any data that you would not like compromised (i.e. personal photos) into the system. **Use at your own risk.**
24 |
25 | ## Installation
26 |
27 | Requires MongoDB and Redis instances. To install, clone the repo and then create a config.js file in the root folder of the application (the one with app.js). Then include the following in the file:
28 |
29 | ```
30 | module.exports = {
31 | mongoURL : 'mongodb://[host]:[port]/[DB]',
32 | mongoOptions : {
33 | user : '[username]',
34 | pass : '[password]'
35 | },
36 | redisURL: 'redis://x:[password]@[host]:[port]',
37 | deleteSnaps: true
38 | }
39 | ```
40 | As you can imagine, the ```deleteSnaps``` option determines whether snaps are deleted. If set to false, The user may review any snaps she or he has received repeatedly.
41 |
42 | ## Program Structure
43 |
44 | The app bootstraps from **app.js** which connects to the databases and enables the API routes. All the routes and middlewares are outlined in **routes.js**, also in the same folders. The meat of the API calls are in the controllers folder in the app root. Users are stored in MongoDB, for which the models resides in the models folder. The systems folder contains misc code that is to be reused throughout the backend (passport bootstrapping, redis connection, cron job to delete snaps, etc.)
45 |
46 | All the client (i.e. browser) content resides in the public folder. If you're familiar with Angular, the structure should be clear enough. All the html files are stored in view. Each html has a corresponding controller in the public/javascripts/controllers folder. The angular app is bootstrapped in **core.js**, which is in the javascripts folder.
47 |
48 | The bin folder is for Azure to start an instance of the app.
49 |
50 | ## Contributors
51 |
52 | * Mostafa Saadat - Tested app functionality throughout the hacking process, made favicon
53 | * Afuad Hossain - Discovered bug in friending functionality during use
54 | * Zack Ohlin - Discovered bug in friending functionality during use
55 | * 'Daft Monk' - Used his [Angular-Passport CRUD demo] (https://github.com/DaftMonk/angular-passport) as the inspiration RedSnap's auth system
56 |
57 | ## License
58 |
59 | [MIT] (https://github.com/gaessaki/RedSnap/blob/master/LICENSE)
60 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/providers/socket.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @license
3 | * angular-socket-io v0.7.0
4 | * (c) 2014 Brian Ford http://briantford.com
5 | * License: MIT
6 | */
7 |
8 | angular.module('btford.socket-io', []).
9 | provider('socketFactory', function () {
10 |
11 | 'use strict';
12 |
13 | // when forwarding events, prefix the event name
14 | var defaultPrefix = 'socket:',
15 | ioSocket;
16 |
17 | // expose to provider
18 | this.$get = ['$rootScope', '$timeout', function ($rootScope, $timeout) {
19 |
20 | var asyncAngularify = function (socket, callback) {
21 | return callback ? function () {
22 | var args = arguments;
23 | $timeout(function () {
24 | callback.apply(socket, args);
25 | }, 0);
26 | } : angular.noop;
27 | };
28 |
29 | return function socketFactory(options) {
30 | options = options || {};
31 | var socket = options.ioSocket || io.connect();
32 | var prefix = options.prefix === undefined ? defaultPrefix : options.prefix;
33 | var defaultScope = options.scope || $rootScope;
34 |
35 | var addListener = function (eventName, callback) {
36 | socket.on(eventName, callback.__ng = asyncAngularify(socket, callback));
37 | };
38 |
39 | var addOnceListener = function (eventName, callback) {
40 | socket.once(eventName, callback.__ng = asyncAngularify(socket, callback));
41 | };
42 |
43 | var wrappedSocket = {
44 | on: addListener,
45 | addListener: addListener,
46 | once: addOnceListener,
47 |
48 | emit: function (eventName, data, callback) {
49 | var lastIndex = arguments.length - 1;
50 | var callback = arguments[lastIndex];
51 | if (typeof callback == 'function') {
52 | callback = asyncAngularify(socket, callback);
53 | arguments[lastIndex] = callback;
54 | }
55 | return socket.emit.apply(socket, arguments);
56 | },
57 |
58 | removeListener: function (ev, fn) {
59 | if (fn && fn.__ng) {
60 | arguments[1] = fn.__ng;
61 | }
62 | return socket.removeListener.apply(socket, arguments);
63 | },
64 |
65 | removeAllListeners: function () {
66 | return socket.removeAllListeners.apply(socket, arguments);
67 | },
68 |
69 | disconnect: function (close) {
70 | return socket.disconnect(close);
71 | },
72 |
73 | connect: function () {
74 | return socket.connect();
75 | },
76 |
77 | // when socket.on('someEvent', fn (data) { ... }),
78 | // call scope.$broadcast('someEvent', data)
79 | forward: function (events, scope) {
80 | if (events instanceof Array === false) {
81 | events = [events];
82 | }
83 | if (!scope) {
84 | scope = defaultScope;
85 | }
86 | events.forEach(function (eventName) {
87 | var prefixedEvent = prefix + eventName;
88 | var forwardBroadcast = asyncAngularify(socket, function () {
89 | Array.prototype.unshift.call(arguments, prefixedEvent);
90 | scope.$broadcast.apply(scope, arguments);
91 | });
92 | scope.$on('$destroy', function () {
93 | socket.removeListener(eventName, forwardBroadcast);
94 | });
95 | socket.on(eventName, forwardBroadcast);
96 | });
97 | }
98 | };
99 |
100 | return wrappedSocket;
101 | };
102 | }];
103 | });
104 |
105 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/providers/socket.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @license
3 | * angular-socket-io v0.7.0
4 | * (c) 2014 Brian Ford http://briantford.com
5 | * License: MIT
6 | */
7 |
8 | angular.module('btford.socket-io', []).
9 | provider('socketFactory', function () {
10 |
11 | 'use strict';
12 |
13 | // when forwarding events, prefix the event name
14 | var defaultPrefix = 'socket:',
15 | ioSocket;
16 |
17 | // expose to provider
18 | this.$get = ['$rootScope', '$timeout', function ($rootScope, $timeout) {
19 |
20 | var asyncAngularify = function (socket, callback) {
21 | return callback ? function () {
22 | var args = arguments;
23 | $timeout(function () {
24 | callback.apply(socket, args);
25 | }, 0);
26 | } : angular.noop;
27 | };
28 |
29 | return function socketFactory(options) {
30 | options = options || {};
31 | var socket = options.ioSocket || io.connect();
32 | var prefix = options.prefix === undefined ? defaultPrefix : options.prefix;
33 | var defaultScope = options.scope || $rootScope;
34 |
35 | var addListener = function (eventName, callback) {
36 | socket.on(eventName, callback.__ng = asyncAngularify(socket, callback));
37 | };
38 |
39 | var addOnceListener = function (eventName, callback) {
40 | socket.once(eventName, callback.__ng = asyncAngularify(socket, callback));
41 | };
42 |
43 | var wrappedSocket = {
44 | on: addListener,
45 | addListener: addListener,
46 | once: addOnceListener,
47 |
48 | emit: function (eventName, data, callback) {
49 | var lastIndex = arguments.length - 1;
50 | var callback = arguments[lastIndex];
51 | if (typeof callback == 'function') {
52 | callback = asyncAngularify(socket, callback);
53 | arguments[lastIndex] = callback;
54 | }
55 | return socket.emit.apply(socket, arguments);
56 | },
57 |
58 | removeListener: function (ev, fn) {
59 | if (fn && fn.__ng) {
60 | arguments[1] = fn.__ng;
61 | }
62 | return socket.removeListener.apply(socket, arguments);
63 | },
64 |
65 | removeAllListeners: function () {
66 | return socket.removeAllListeners.apply(socket, arguments);
67 | },
68 |
69 | disconnect: function (close) {
70 | return socket.disconnect(close);
71 | },
72 |
73 | connect: function () {
74 | return socket.connect();
75 | },
76 |
77 | // when socket.on('someEvent', fn (data) { ... }),
78 | // call scope.$broadcast('someEvent', data)
79 | forward: function (events, scope) {
80 | if (events instanceof Array === false) {
81 | events = [events];
82 | }
83 | if (!scope) {
84 | scope = defaultScope;
85 | }
86 | events.forEach(function (eventName) {
87 | var prefixedEvent = prefix + eventName;
88 | var forwardBroadcast = asyncAngularify(socket, function () {
89 | Array.prototype.unshift.call(arguments, prefixedEvent);
90 | scope.$broadcast.apply(scope, arguments);
91 | });
92 | scope.$on('$destroy', function () {
93 | socket.removeListener(eventName, forwardBroadcast);
94 | });
95 | socket.on(eventName, forwardBroadcast);
96 | });
97 | }
98 | };
99 |
100 | return wrappedSocket;
101 | };
102 | }];
103 | });
104 |
105 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | RedSnap - Open Source Web SnapChat Clone
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
89 |
90 |
93 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | RedSnap - Open Source Web SnapChat Clone
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
89 |
90 |
93 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/services/http-auth-interceptor.js:
--------------------------------------------------------------------------------
1 | /*global angular:true, browser:true */
2 |
3 | /**
4 | * @license HTTP Auth Interceptor Module for AngularJS
5 | * (c) 2012 Witold Szczerba
6 | * License: MIT
7 | */
8 | (function () {
9 | 'use strict';
10 |
11 | angular.module('http-auth-interceptor', ['http-auth-interceptor-buffer'])
12 |
13 | .factory('authService', ['$rootScope', 'httpBuffer', function ($rootScope, httpBuffer) {
14 | return {
15 | /**
16 | * Call this function to indicate that authentication was successfull and trigger a
17 | * retry of all deferred requests.
18 | * @param data an optional argument to pass on to $broadcast which may be useful for
19 | * example if you need to pass through details of the user that was logged in
20 | * @param configUpdater an optional transformation function that can modify the
21 | * requests that are retried after having logged in. This can be used for example
22 | * to add an authentication token. It must return the request.
23 | */
24 | loginConfirmed: function (data, configUpdater) {
25 | var updater = configUpdater || function (config) { return config; };
26 | $rootScope.$broadcast('event:auth-loginConfirmed', data);
27 | httpBuffer.retryAll(updater);
28 | },
29 |
30 | /**
31 | * Call this function to indicate that authentication should not proceed.
32 | * All deferred requests will be abandoned or rejected (if reason is provided).
33 | * @param data an optional argument to pass on to $broadcast.
34 | * @param reason if provided, the requests are rejected; abandoned otherwise.
35 | */
36 | loginCancelled: function (data, reason) {
37 | httpBuffer.rejectAll(reason);
38 | $rootScope.$broadcast('event:auth-loginCancelled', data);
39 | }
40 | };
41 | }])
42 |
43 | /**
44 | * $http interceptor.
45 | * On 401 response (without 'ignoreAuthModule' option) stores the request
46 | * and broadcasts 'event:auth-loginRequired'.
47 | * On 403 response (without 'ignoreAuthModule' option) discards the request
48 | * and broadcasts 'event:auth-forbidden'.
49 | */
50 | .config(['$httpProvider', function ($httpProvider) {
51 | $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function ($rootScope, $q, httpBuffer) {
52 | return {
53 | responseError: function (rejection) {
54 | var config = rejection.config || {};
55 | if (!config.ignoreAuthModule) {
56 | switch (rejection.status) {
57 | case 401:
58 | var deferred = $q.defer();
59 | httpBuffer.append(config, deferred);
60 | $rootScope.$broadcast('event:auth-loginRequired', rejection);
61 | return deferred.promise;
62 | case 403:
63 | $rootScope.$broadcast('event:auth-forbidden', rejection);
64 | break;
65 | }
66 | }
67 | // otherwise, default behaviour
68 | return $q.reject(rejection);
69 | }
70 | };
71 | }]);
72 | }]);
73 |
74 | /**
75 | * Private module, a utility, required internally by 'http-auth-interceptor'.
76 | */
77 | angular.module('http-auth-interceptor-buffer', [])
78 |
79 | .factory('httpBuffer', ['$injector', function ($injector) {
80 | /** Holds all the requests, so they can be re-requested in future. */
81 | var buffer = [];
82 |
83 | /** Service initialized later because of circular dependency problem. */
84 | var $http;
85 |
86 | function retryHttpRequest(config, deferred) {
87 | function successCallback(response) {
88 | deferred.resolve(response);
89 | }
90 | function errorCallback(response) {
91 | deferred.reject(response);
92 | }
93 | $http = $http || $injector.get('$http');
94 | $http(config).then(successCallback, errorCallback);
95 | }
96 |
97 | return {
98 | /**
99 | * Appends HTTP request configuration object with deferred response attached to buffer.
100 | */
101 | append: function (config, deferred) {
102 | buffer.push({
103 | config: config,
104 | deferred: deferred
105 | });
106 | },
107 |
108 | /**
109 | * Abandon or reject (if reason provided) all the buffered requests.
110 | */
111 | rejectAll: function (reason) {
112 | if (reason) {
113 | for (var i = 0; i < buffer.length; ++i) {
114 | buffer[i].deferred.reject(reason);
115 | }
116 | }
117 | buffer = [];
118 | },
119 |
120 | /**
121 | * Retries all the buffered requests clears the buffer.
122 | */
123 | retryAll: function (updater) {
124 | for (var i = 0; i < buffer.length; ++i) {
125 | retryHttpRequest(updater(buffer[i].config), buffer[i].deferred);
126 | }
127 | buffer = [];
128 | }
129 | };
130 | }]);
131 | })();
132 |
133 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/services/http-auth-interceptor.js:
--------------------------------------------------------------------------------
1 | /*global angular:true, browser:true */
2 |
3 | /**
4 | * @license HTTP Auth Interceptor Module for AngularJS
5 | * (c) 2012 Witold Szczerba
6 | * License: MIT
7 | */
8 | (function () {
9 | 'use strict';
10 |
11 | angular.module('http-auth-interceptor', ['http-auth-interceptor-buffer'])
12 |
13 | .factory('authService', ['$rootScope', 'httpBuffer', function ($rootScope, httpBuffer) {
14 | return {
15 | /**
16 | * Call this function to indicate that authentication was successfull and trigger a
17 | * retry of all deferred requests.
18 | * @param data an optional argument to pass on to $broadcast which may be useful for
19 | * example if you need to pass through details of the user that was logged in
20 | * @param configUpdater an optional transformation function that can modify the
21 | * requests that are retried after having logged in. This can be used for example
22 | * to add an authentication token. It must return the request.
23 | */
24 | loginConfirmed: function (data, configUpdater) {
25 | var updater = configUpdater || function (config) { return config; };
26 | $rootScope.$broadcast('event:auth-loginConfirmed', data);
27 | httpBuffer.retryAll(updater);
28 | },
29 |
30 | /**
31 | * Call this function to indicate that authentication should not proceed.
32 | * All deferred requests will be abandoned or rejected (if reason is provided).
33 | * @param data an optional argument to pass on to $broadcast.
34 | * @param reason if provided, the requests are rejected; abandoned otherwise.
35 | */
36 | loginCancelled: function (data, reason) {
37 | httpBuffer.rejectAll(reason);
38 | $rootScope.$broadcast('event:auth-loginCancelled', data);
39 | }
40 | };
41 | }])
42 |
43 | /**
44 | * $http interceptor.
45 | * On 401 response (without 'ignoreAuthModule' option) stores the request
46 | * and broadcasts 'event:auth-loginRequired'.
47 | * On 403 response (without 'ignoreAuthModule' option) discards the request
48 | * and broadcasts 'event:auth-forbidden'.
49 | */
50 | .config(['$httpProvider', function ($httpProvider) {
51 | $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function ($rootScope, $q, httpBuffer) {
52 | return {
53 | responseError: function (rejection) {
54 | var config = rejection.config || {};
55 | if (!config.ignoreAuthModule) {
56 | switch (rejection.status) {
57 | case 401:
58 | var deferred = $q.defer();
59 | httpBuffer.append(config, deferred);
60 | $rootScope.$broadcast('event:auth-loginRequired', rejection);
61 | return deferred.promise;
62 | case 403:
63 | $rootScope.$broadcast('event:auth-forbidden', rejection);
64 | break;
65 | }
66 | }
67 | // otherwise, default behaviour
68 | return $q.reject(rejection);
69 | }
70 | };
71 | }]);
72 | }]);
73 |
74 | /**
75 | * Private module, a utility, required internally by 'http-auth-interceptor'.
76 | */
77 | angular.module('http-auth-interceptor-buffer', [])
78 |
79 | .factory('httpBuffer', ['$injector', function ($injector) {
80 | /** Holds all the requests, so they can be re-requested in future. */
81 | var buffer = [];
82 |
83 | /** Service initialized later because of circular dependency problem. */
84 | var $http;
85 |
86 | function retryHttpRequest(config, deferred) {
87 | function successCallback(response) {
88 | deferred.resolve(response);
89 | }
90 | function errorCallback(response) {
91 | deferred.reject(response);
92 | }
93 | $http = $http || $injector.get('$http');
94 | $http(config).then(successCallback, errorCallback);
95 | }
96 |
97 | return {
98 | /**
99 | * Appends HTTP request configuration object with deferred response attached to buffer.
100 | */
101 | append: function (config, deferred) {
102 | buffer.push({
103 | config: config,
104 | deferred: deferred
105 | });
106 | },
107 |
108 | /**
109 | * Abandon or reject (if reason provided) all the buffered requests.
110 | */
111 | rejectAll: function (reason) {
112 | if (reason) {
113 | for (var i = 0; i < buffer.length; ++i) {
114 | buffer[i].deferred.reject(reason);
115 | }
116 | }
117 | buffer = [];
118 | },
119 |
120 | /**
121 | * Retries all the buffered requests clears the buffer.
122 | */
123 | retryAll: function (updater) {
124 | for (var i = 0; i < buffer.length; ++i) {
125 | retryHttpRequest(updater(buffer[i].config), buffer[i].deferred);
126 | }
127 | buffer = [];
128 | }
129 | };
130 | }]);
131 | })();
132 |
133 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/controllers/user.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose'),
2 | User = mongoose.model('User'),
3 | passport = require('passport');
4 |
5 | exports.register = function (req, res, next) {
6 | console.log("registering user")
7 | var registrant = new User({
8 | username : req.body.username,
9 | password : req.body.password,
10 | email : req.body.email
11 | });
12 |
13 | registrant.save(function (err) {
14 | if (err) {
15 | console.log(err)
16 | return res.json(err)
17 | }
18 | })
19 |
20 | req.logIn(registrant, function (err) {
21 | if (err) return next(err);
22 | return res.json(registrant.user_info);
23 | })
24 | }
25 |
26 | exports.friends = function (req, res, next) {
27 | console.log('listing friends for ' + req.user.username)
28 | User.findOne({ 'username': req.user.username }, 'friends', function (err, user) {
29 | console.log(user.friends);
30 | return res.json(user.friends);
31 | })
32 | }
33 |
34 | exports.friend = function (req, res, next) {
35 | if (!req.body.friend) {
36 | console.log("No friend added");
37 | return res.send().status(400).end();
38 | }
39 | console.log(req.user.username + ' is attempting to friend ' + req.body.friend)
40 | if (req.user.username == req.body.friend) {
41 | console.log("Can't friend yourself!");
42 | return res.send().status(400).end();
43 | }
44 | else {
45 | User.findOne({ 'username' : req.body.friend }, function (err, user) {
46 | if (err || !user) {
47 | console.log(err)
48 | return res.send(err).status(400).end();//user presumably not found
49 | }
50 | var isCurrFriend = user.user_info.friends.current.map(function (e) { return e.username; }).indexOf(req.user.username);
51 | var isReqFriend = user.user_info.friends.requested.map(function (e) { return e.username; }).indexOf(req.user.username);
52 | if (isCurrFriend != -1) {
53 | console.log(req.user.username + ' is already friends with ' + req.body.friend)
54 | return res.send(req.user.username + ' is already friends with ' + req.body.friend).status(400).end()
55 | //return res.json(req.user.username + ' is already friends with ' + req.body.friend)
56 | }
57 | else {
58 | User.findOne({ 'username' : req.user.username }, function (err, currUser) {
59 | if (err) {
60 | console.log(err)
61 | return res.send(err).status(400).end(); //user presumably not found, but how would that even be possible?
62 | }
63 | var isUserFriendIndex = currUser.user_info.friends.requested.map(function (e) { return e.username; }).indexOf(user.username); //currUser.user_info.friends.requested.indexOf(user.username);
64 | console.log(isUserFriendIndex)
65 | if (isUserFriendIndex != -1) { //is there an existing request from interested party? If so, both users should be friends now
66 |
67 | User.findOneAndUpdate({ 'username' : req.user.username }, {
68 | $push: {
69 | 'friends.current' : {
70 | '_id': user._id,
71 | 'username': user.username
72 | }
73 | },
74 | $pull: {
75 | 'friends.requested' : {
76 | 'username': user.username
77 | }
78 | }
79 |
80 | }, function (err, us) {
81 | if (err) console.log(err);
82 | })
83 | User.findOneAndUpdate({ 'username' : req.body.friend }, {
84 | $push: {
85 | 'friends.current' : {
86 | '_id': currUser._id,
87 | 'username': currUser.username
88 | }
89 | }
90 | }, function (err, us) {
91 | if (err) console.log(err);
92 | return res.send().status(200).end();
93 | })
94 | }
95 | else if (isReqFriend) { //Did the user send a request to the friend in the past? If not, then send it now
96 | user.user_info.friends.requested.push({ _id: req.user._id, username: req.user.username });
97 | User.findOneAndUpdate({ 'username' : req.body.friend }, user, function (err, us) {
98 | if (err) console.log(err);
99 | })
100 | return res.send().status(200).end();
101 | }
102 | else {
103 | return res.send().status(404).end();
104 | }
105 | })
106 | }
107 | })
108 | }
109 |
110 | }
111 | //check if friend exists
112 | //check if friend already
113 | //check if user has already send request
114 | //if so then confirm that both are now friends, remove requested friend for both users and add current for both
115 | //if not then set user as requested friend for target
116 |
117 | exports.unfriend = function (req, res, next) {
118 | console.log(req.user.username + " is trying to unfriend " + req.query.friend)
119 | User.findOneAndUpdate({ 'username' : req.query.friend }, {
120 | $pull : {
121 | 'friends.current' : {
122 | 'username': req.user.username
123 | }
124 | }
125 | }, function (err, user) {
126 | if (err) {
127 | console.log(err);
128 | return res.send(err);
129 | }
130 | })
131 | User.findOneAndUpdate({ 'username' : req.user.username }, {
132 | $pull : {
133 | 'friends.current' : {
134 | 'username': req.query.friend
135 | }
136 | }
137 | }, function (err, user) {
138 | if (err) {
139 | console.log(err);
140 | return res.send(err);
141 | }
142 | else {
143 | }
144 | })
145 | return res.send().status(200).end()
146 | }
147 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/public/javascripts/directives/webcam.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Webcam Directive
3 | *
4 | * (c) Jonas Hartmann http://jonashartmann.github.io/webcam-directive
5 | * License: MIT
6 | *
7 | * @version: 3.1.0
8 | */
9 | 'use strict';
10 |
11 | (function () {
12 | // GetUserMedia is not yet supported by all browsers
13 | // Until then, we need to handle the vendor prefixes
14 | navigator.getMedia = (navigator.getUserMedia ||
15 | navigator.webkitGetUserMedia ||
16 | navigator.mozGetUserMedia ||
17 | navigator.msGetUserMedia);
18 |
19 | // Checks if getUserMedia is available on the client browser
20 | window.hasUserMedia = function hasUserMedia() {
21 | return navigator.getMedia ? true : false;
22 | };
23 | })();
24 |
25 | angular.module('webcam', [])
26 | .directive('webcam', function () {
27 | return {
28 | template: '
',
29 | restrict: 'E',
30 | replace: true,
31 | transclude: true,
32 | scope:
33 | {
34 | onError: '&',
35 | onStream: '&',
36 | onStreaming: '&',
37 | placeholder: '=',
38 | config: '=channel'
39 | },
40 | link: function postLink($scope, element) {
41 | var videoElem = null,
42 | videoStream = null,
43 | placeholder = null;
44 |
45 | $scope.config = $scope.config || {};
46 |
47 | var _removeDOMElement = function _removeDOMElement(DOMel) {
48 | if (DOMel) {
49 | angular.element(DOMel).remove();
50 | }
51 | };
52 |
53 | var onDestroy = function onDestroy() {
54 | if (!!videoStream) {
55 | var checker = typeof videoStream.getVideoTracks === 'function';
56 | if (videoStream.getVideoTracks && checker) {
57 | // get video track to call stop in it
58 | // videoStream.stop() is deprecated and may be removed in the
59 | // near future
60 | // ENSURE THIS IS CHECKED FIRST BEFORE THE FALLBACK
61 | // videoStream.stop()
62 | var tracks = videoStream.getVideoTracks();
63 | if (tracks && tracks[0] && tracks[0].stop) {
64 | tracks[0].stop();
65 | }
66 | } else if (videoStream.stop) {
67 | // deprecated, may be removed in the near future
68 | videoStream.stop();
69 | }
70 | }
71 | if (!!videoElem) {
72 | delete videoElem.src;
73 | }
74 | };
75 |
76 | // called when camera stream is loaded
77 | var onSuccess = function onSuccess(stream) {
78 | videoStream = stream;
79 |
80 | // Firefox supports a src object
81 | if (navigator.mozGetUserMedia) {
82 | videoElem.mozSrcObject = stream;
83 | } else {
84 | var vendorURL = window.URL || window.webkitURL;
85 | videoElem.src = vendorURL.createObjectURL(stream);
86 | }
87 |
88 | /* Start playing the video to show the stream from the webcam */
89 | videoElem.play();
90 | $scope.config.video = videoElem;
91 |
92 | /* Call custom callback */
93 | if ($scope.onStream) {
94 | $scope.onStream({ stream: stream });
95 | }
96 | };
97 |
98 | // called when any error happens
99 | var onFailure = function onFailure(err) {
100 | _removeDOMElement(placeholder);
101 | if (console && console.log) {
102 | console.log('The following error occured: ', err);
103 | }
104 |
105 | /* Call custom callback */
106 | if ($scope.onError) {
107 | $scope.onError({ err: err });
108 | }
109 |
110 | return;
111 | };
112 |
113 | var startWebcam = function startWebcam() {
114 | videoElem = document.createElement('video');
115 | videoElem.setAttribute('class', 'webcam-live');
116 | videoElem.setAttribute('autoplay', '');
117 | element.append(videoElem);
118 |
119 | if ($scope.placeholder) {
120 | placeholder = document.createElement('img');
121 | placeholder.setAttribute('class', 'webcam-loader');
122 | placeholder.src = $scope.placeholder;
123 | element.append(placeholder);
124 | }
125 |
126 | // Default variables
127 | var isStreaming = false,
128 | width = element.width = $scope.config.videoWidth || 320,
129 | height = element.height = 0;
130 |
131 | // Check the availability of getUserMedia across supported browsers
132 | if (!window.hasUserMedia()) {
133 | onFailure({ code: -1, msg: 'Browser does not support getUserMedia.' });
134 | return;
135 | }
136 |
137 | var mediaConstraint = { video: true, audio: false };
138 | navigator.getMedia(mediaConstraint, onSuccess, onFailure);
139 |
140 | /* Start streaming the webcam data when the video element can play
141 | * It will do it only once
142 | */
143 | videoElem.addEventListener('canplay', function () {
144 | if (!isStreaming) {
145 | var scale = width / videoElem.videoWidth;
146 | height = (videoElem.videoHeight * scale) || $scope.config.videoHeight;
147 | videoElem.setAttribute('width', width);
148 | videoElem.setAttribute('height', height);
149 | isStreaming = true;
150 |
151 | $scope.config.video = videoElem;
152 |
153 | _removeDOMElement(placeholder);
154 |
155 | /* Call custom callback */
156 | if ($scope.onStreaming) {
157 | $scope.onStreaming();
158 | }
159 | }
160 | }, false);
161 | };
162 |
163 | var stopWebcam = function stopWebcam() {
164 | onDestroy();
165 | videoElem.remove();
166 | };
167 |
168 | $scope.$on('$destroy', onDestroy);
169 | $scope.$on('START_WEBCAM', startWebcam);
170 | $scope.$on('STOP_WEBCAM', stopWebcam);
171 |
172 | startWebcam();
173 |
174 | }
175 | };
176 | });
177 |
178 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/obj/Release/Package/PackageTmp/public/javascripts/directives/webcam.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Webcam Directive
3 | *
4 | * (c) Jonas Hartmann http://jonashartmann.github.io/webcam-directive
5 | * License: MIT
6 | *
7 | * @version: 3.1.0
8 | */
9 | 'use strict';
10 |
11 | (function () {
12 | // GetUserMedia is not yet supported by all browsers
13 | // Until then, we need to handle the vendor prefixes
14 | navigator.getMedia = (navigator.getUserMedia ||
15 | navigator.webkitGetUserMedia ||
16 | navigator.mozGetUserMedia ||
17 | navigator.msGetUserMedia);
18 |
19 | // Checks if getUserMedia is available on the client browser
20 | window.hasUserMedia = function hasUserMedia() {
21 | return navigator.getMedia ? true : false;
22 | };
23 | })();
24 |
25 | angular.module('webcam', [])
26 | .directive('webcam', function () {
27 | return {
28 | template: '
',
29 | restrict: 'E',
30 | replace: true,
31 | transclude: true,
32 | scope:
33 | {
34 | onError: '&',
35 | onStream: '&',
36 | onStreaming: '&',
37 | placeholder: '=',
38 | config: '=channel'
39 | },
40 | link: function postLink($scope, element) {
41 | var videoElem = null,
42 | videoStream = null,
43 | placeholder = null;
44 |
45 | $scope.config = $scope.config || {};
46 |
47 | var _removeDOMElement = function _removeDOMElement(DOMel) {
48 | if (DOMel) {
49 | angular.element(DOMel).remove();
50 | }
51 | };
52 |
53 | var onDestroy = function onDestroy() {
54 | if (!!videoStream) {
55 | var checker = typeof videoStream.getVideoTracks === 'function';
56 | if (videoStream.getVideoTracks && checker) {
57 | // get video track to call stop in it
58 | // videoStream.stop() is deprecated and may be removed in the
59 | // near future
60 | // ENSURE THIS IS CHECKED FIRST BEFORE THE FALLBACK
61 | // videoStream.stop()
62 | var tracks = videoStream.getVideoTracks();
63 | if (tracks && tracks[0] && tracks[0].stop) {
64 | tracks[0].stop();
65 | }
66 | } else if (videoStream.stop) {
67 | // deprecated, may be removed in the near future
68 | videoStream.stop();
69 | }
70 | }
71 | if (!!videoElem) {
72 | delete videoElem.src;
73 | }
74 | };
75 |
76 | // called when camera stream is loaded
77 | var onSuccess = function onSuccess(stream) {
78 | videoStream = stream;
79 |
80 | // Firefox supports a src object
81 | if (navigator.mozGetUserMedia) {
82 | videoElem.mozSrcObject = stream;
83 | } else {
84 | var vendorURL = window.URL || window.webkitURL;
85 | videoElem.src = vendorURL.createObjectURL(stream);
86 | }
87 |
88 | /* Start playing the video to show the stream from the webcam */
89 | videoElem.play();
90 | $scope.config.video = videoElem;
91 |
92 | /* Call custom callback */
93 | if ($scope.onStream) {
94 | $scope.onStream({ stream: stream });
95 | }
96 | };
97 |
98 | // called when any error happens
99 | var onFailure = function onFailure(err) {
100 | _removeDOMElement(placeholder);
101 | if (console && console.log) {
102 | console.log('The following error occured: ', err);
103 | }
104 |
105 | /* Call custom callback */
106 | if ($scope.onError) {
107 | $scope.onError({ err: err });
108 | }
109 |
110 | return;
111 | };
112 |
113 | var startWebcam = function startWebcam() {
114 | videoElem = document.createElement('video');
115 | videoElem.setAttribute('class', 'webcam-live');
116 | videoElem.setAttribute('autoplay', '');
117 | element.append(videoElem);
118 |
119 | if ($scope.placeholder) {
120 | placeholder = document.createElement('img');
121 | placeholder.setAttribute('class', 'webcam-loader');
122 | placeholder.src = $scope.placeholder;
123 | element.append(placeholder);
124 | }
125 |
126 | // Default variables
127 | var isStreaming = false,
128 | width = element.width = $scope.config.videoWidth || 320,
129 | height = element.height = 0;
130 |
131 | // Check the availability of getUserMedia across supported browsers
132 | if (!window.hasUserMedia()) {
133 | onFailure({ code: -1, msg: 'Browser does not support getUserMedia.' });
134 | return;
135 | }
136 |
137 | var mediaConstraint = { video: true, audio: false };
138 | navigator.getMedia(mediaConstraint, onSuccess, onFailure);
139 |
140 | /* Start streaming the webcam data when the video element can play
141 | * It will do it only once
142 | */
143 | videoElem.addEventListener('canplay', function () {
144 | if (!isStreaming) {
145 | var scale = width / videoElem.videoWidth;
146 | height = (videoElem.videoHeight * scale) || $scope.config.videoHeight;
147 | videoElem.setAttribute('width', width);
148 | videoElem.setAttribute('height', height);
149 | isStreaming = true;
150 |
151 | $scope.config.video = videoElem;
152 |
153 | _removeDOMElement(placeholder);
154 |
155 | /* Call custom callback */
156 | if ($scope.onStreaming) {
157 | $scope.onStreaming();
158 | }
159 | }
160 | }, false);
161 | };
162 |
163 | var stopWebcam = function stopWebcam() {
164 | onDestroy();
165 | videoElem.remove();
166 | };
167 |
168 | $scope.$on('$destroy', onDestroy);
169 | $scope.$on('START_WEBCAM', startWebcam);
170 | $scope.$on('STOP_WEBCAM', stopWebcam);
171 |
172 | startWebcam();
173 |
174 | }
175 | };
176 | });
177 |
178 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/RedSnap.njsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 11.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 | RedSnap
7 | RedSnap
8 |
9 |
10 |
11 | Debug
12 | 2.0
13 | da47b884-6324-463e-bf38-692f7f7a3f32
14 | .
15 | bin\www
16 |
17 |
18 | .
19 | .
20 | v4.0
21 | {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}
22 | ShowAllFiles
23 | 1337
24 | true
25 |
26 |
27 | true
28 |
29 |
30 | true
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | False
117 | True
118 | 0
119 | /
120 | http://localhost:48022/
121 | False
122 | True
123 | http://localhost:1337
124 | False
125 |
126 |
127 |
128 |
129 |
130 |
131 | CurrentPage
132 | True
133 | False
134 | False
135 | False
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | False
145 | False
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/RedSnap/RedSnap/controllers/snap.js:
--------------------------------------------------------------------------------
1 | var redis = require('redis');
2 | var async = require('async');
3 | var mkdirp = require('mkdirp');
4 | var crypto = require('crypto');
5 | var uuid = require('node-uuid');
6 | const fs = require('fs');
7 |
8 | var conf = require('../config')
9 |
10 | var mongoose = require('mongoose'),
11 | User = mongoose.model('User');
12 | var client = require('../systems/rediscon.js');
13 |
14 | exports.receivesnaps = function (req, res, next) {
15 | var snaps = []
16 | client.lrange(req.user.username, 0, -1, function (err, obj) {
17 | if (err) {
18 | console.log(err)
19 | return res.status(400).send().end();
20 | }
21 | else {
22 | console.log(obj)
23 | async.each(obj, function (item, cb) {
24 | client.hgetall(item, function (err, snapHash) {
25 | if (err) {
26 | console.log(err);
27 | }
28 | snaps.push(snap = {
29 | id: item,
30 | sender: snapHash.sender
31 | });
32 | console.log(item);
33 | cb();
34 | })
35 | }, function () {
36 | if (snaps) {
37 | console.log(200)
38 | return res.status(200).send(snaps);
39 | }
40 | })
41 | }
42 | })
43 | }
44 |
45 | exports.viewsnap = function (req, res, next) {
46 | var snapResData = {}
47 | var dataURIIdentifier = "data:image/png;base64,";
48 | client.hgetall(req.body.snapInfo.id, function (err, snapHash) {
49 | if (err) {
50 | console.log(err);
51 | return res.status(400).end();
52 | }
53 | else {
54 | fs.readFile(snapHash.imgloc, 'base64', function (err, data) {
55 | if (err) console.log(err);
56 | else {
57 | var imgdata = dataURIIdentifier.concat(data);
58 | snapResData = {
59 | id: req.body.snapInfo.id,
60 | sender: snapHash.sender,
61 | time: snapHash.time,
62 | msg: snapHash.msg,
63 | imgData: imgdata
64 | }
65 |
66 | if (conf.deleteSnaps) {
67 | var friendsArr = snapHash.friends.split(','); //regex may be better for this
68 | var ind = friendsArr.indexOf(req.user.username);
69 | var friendsStr = "";
70 | console.log(friendsArr)
71 | friendsArr.splice(ind, 1)
72 |
73 | //Check if there are more friends that need to see snap, if not, then queue snap for deletion
74 | if (friendsArr != ['']) {
75 | for (i = 0; i < friendsArr.length; i++) {
76 | friendsStr = friendsStr.concat(req.user.username + ',');
77 | }
78 | }
79 | else {
80 | client.lpush('deletion', req.body.snapInfo.id)
81 | }
82 |
83 | client.hset(req.body.snapInfo.id, 'friends', friendsStr);
84 | client.lrem(req.user.username, 1, req.body.snapInfo.id);
85 | }
86 | return res.status(200).json(snapResData);
87 | }
88 | })
89 | }
90 | })
91 | }
92 |
93 | exports.sendsnaps = function (req, res, next) {
94 | if (req.body.snap.friends.length < 1) {
95 | console.log("No friends selected!");
96 | return res.status(400).send("No friends were selected!");
97 | }
98 |
99 | var md5sum = crypto.createHash('md5').update(req.user.username + new Date().toString()).digest('hex');
100 | var dirPath = './snapStorage/'
101 | + md5sum.substring(0, 2) + '/'
102 | + md5sum.substring(2, 4) + '/'
103 | + md5sum.substring(4, 7) + '/'
104 | + md5sum.substring(7, 14) + '/';
105 |
106 | mkdirp(dirPath, function (err) {
107 | if (err) {
108 | console.log(err + 'ho')
109 | return res.status(400).send(err).end();
110 | }
111 | else {
112 | var b64imgData = req.body.snap.img.replace(/^data:image\/png;base64,/, "");
113 | fs.writeFile(dirPath + md5sum.substring(14, 32) + '.txt', b64imgData, 'base64', function (err) {
114 | if (err) {
115 | console.log(err + 'eh')
116 | return res.status(400).send(err).end();
117 | }
118 | else {
119 | incrSnapSentCount(req.user.username, function (err) {
120 | if (err) {
121 | console.log(err + 'ah')
122 | return res.status(400).send(err).end()
123 | }
124 | else {
125 | var snap_id = uuid.v4();
126 | var friendArrayString = ""; //I know this is bad... forgive me
127 | async.each(req.body.snap.friends, function (friend, cb) {
128 | console.log(friend)
129 | incrSnapRecCount(friend, function (err) {
130 | if (err) {
131 | return cb(err)
132 | }
133 | else {
134 | client.lpush(friend, snap_id);
135 | friendArrayString = friendArrayString.concat(friend + ',')
136 | cb();
137 | }
138 | })
139 | }, function (err) {
140 | if (err) {
141 | console.log(err)
142 | return res.status(400).send(err).end();
143 | }
144 | if (!req.body.snap.text) {
145 | req.body.snap.text = "";
146 | }
147 | client.hmset(snap_id, {
148 | "sender": req.user.username,
149 | "imgloc": dirPath + md5sum.substring(14, 32) + '.txt',
150 | "timestamp": new Date(),
151 | "time": req.body.snap.time,
152 | "msg": req.body.snap.text,
153 | "friends": friendArrayString
154 | });
155 | return res.status(200).send().end();
156 | });
157 | /*for (i = 0; i < req.body.snap.friends.length; i++) {
158 | var friend = req.body.snap.friends[i];
159 |
160 | incrSnapRecCount(friend, function (err) {
161 | if (err) {
162 | console.log(err + 'eh ');
163 | return res.status(400).send(err).end();
164 | }
165 | else {
166 | client.lpush(friend, snap_id);
167 | friendArrayString += ',' + friend;
168 | }
169 | })
170 | }*/
171 |
172 | }
173 | })
174 | }
175 | })
176 | }
177 | })
178 | }
179 |
180 | var incrSnapSentCount = function (name, cb) {
181 | User.findOneAndUpdate({ username: name }, {
182 | $inc : {
183 | 'snap_count.sent' : 1
184 | }
185 | }, function (err, re) {
186 | if (err) {
187 | return cb(err + 'wo');
188 | }
189 | else {
190 | return cb();
191 | }
192 | })
193 | }
194 | var incrSnapRecCount = function (name, cb) {
195 | User.findOneAndUpdate({ username: name }, {
196 | $inc : {
197 | 'snap_count.received' : 1
198 | }
199 | }, function (err, re) {
200 | if (err) {
201 | return cb(err + 'wa');
202 | }
203 | else {
204 | return cb();
205 | }
206 | })
207 | }
208 |
209 | /* for (k = 0; k < obj.length; k++) {
210 |
211 | client.hgetall(obj[k], function (err, snapHash) {
212 | console.log(k)
213 | if (err) {
214 | console.log(err);
215 | return (err, null);
216 | }
217 | else {
218 | snaps.push(snap = {
219 | id: obj[k],
220 | sender: snapHash.sender
221 | });
222 | }
223 | console.log(obj[k]);
224 | //snaps[i].sender = snapHash.sender;
225 | })
226 | } */
227 |
--------------------------------------------------------------------------------