├── .gitattributes
├── .buildignore
├── client
├── robots.txt
├── components
│ ├── footer
│ │ ├── footer.html
│ │ └── footer.directive.js
│ ├── modal
│ │ ├── popUp.html
│ │ ├── modal.css
│ │ ├── modal.controller.js
│ │ ├── views
│ │ │ ├── success.html
│ │ │ └── error.html
│ │ └── modal.service.js
│ ├── header
│ │ ├── header.directive.js
│ │ ├── header.controller.js
│ │ └── header.html
│ ├── messages
│ │ └── messages.js
│ ├── constants
│ │ └── constants.js
│ ├── loader
│ │ └── loader.service.js
│ ├── api-services
│ │ └── user
│ │ │ └── user.service.js
│ ├── config
│ │ └── config.js
│ ├── util
│ │ └── helper.js
│ └── auth
│ │ └── auth.service.js
├── assets
│ └── images
│ │ └── yeoman.png
├── app
│ ├── landing
│ │ ├── landing.html
│ │ ├── landing.controller.js
│ │ └── landing.js
│ ├── home
│ │ ├── home.html
│ │ ├── home.js
│ │ └── home.controller.js
│ ├── account
│ │ ├── changePassword
│ │ │ ├── changePassword.controller.js
│ │ │ └── changePassword.html
│ │ ├── signUp
│ │ │ ├── signUp.controller.js
│ │ │ └── signUp.html
│ │ ├── login
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ ├── forgotPassword
│ │ │ ├── forgotPassword.controller.js
│ │ │ └── forgotPassword.html
│ │ └── account.js
│ ├── interceptor.js
│ ├── app.js
│ └── app.scss
├── test
│ ├── mocked.data.js
│ ├── account
│ │ ├── forgotPassword
│ │ │ └── forgotPassword.controller.spec.js
│ │ ├── login
│ │ │ └── login.controller.spec.js
│ │ ├── signup
│ │ │ └── signup.controller.spec.js
│ │ └── setPassword
│ │ │ └── setPassword.controller.spec.js
│ ├── home
│ │ └── home.controller.spec.js
│ └── landing
│ │ └── landing.controller.spec.js
├── .jshintrc
├── favicon.ico
├── index.html
└── .htaccess
├── .bowerrc
├── .gitignore
├── .travis.yml
├── e2e
└── main
│ ├── main.po.js
│ └── main.spec.js
├── .editorconfig
├── bower.json
├── .yo-rc.json
├── protractor.conf.js
├── server
└── app.js
├── karma.conf.js
├── package.json
├── README.md
└── Gruntfile.js
/.gitattributes:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.buildignore:
--------------------------------------------------------------------------------
1 | *.coffee
--------------------------------------------------------------------------------
/client/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "client/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/client/components/footer/footer.html:
--------------------------------------------------------------------------------
1 |
2 |
Footer
3 |
4 |
--------------------------------------------------------------------------------
/client/assets/images/yeoman.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/princesoni1989/angular-js-seed/HEAD/client/assets/images/yeoman.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | public
3 | .tmp
4 | .sass-cache
5 | .idea
6 | client/bower_components
7 | dist
8 | npm-debug.log
9 | coverage
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | - '0.11'
5 | before_script:
6 | - npm install -g bower grunt-cli
7 | - gem install sass
8 | - bower install
9 |
--------------------------------------------------------------------------------
/client/app/landing/landing.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Hello, world!
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/app/home/home.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/client/components/modal/popUp.html:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/client/app/landing/landing.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function landingCtrl(ModalService) {
6 |
7 | /**
8 | * Controller variables
9 | */
10 | var Landing = this;
11 |
12 | }
13 |
14 | angular.module('angularJsSeedApp')
15 | .controller('LandingCtrl', landingCtrl);
16 |
17 | })(angular)
18 |
--------------------------------------------------------------------------------
/client/components/header/header.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | angular.module('angularJsSeedApp')
6 | .directive('header', function () {
7 | return {
8 | templateUrl: 'components/header/header.html',
9 | restrict: 'E',
10 | controller: 'HeaderCtrl'
11 | };
12 | });
13 |
14 | })(angular)
15 |
16 |
--------------------------------------------------------------------------------
/client/components/messages/messages.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 | //Message constants
5 | function Constants() {
6 | return {
7 | api: {
8 | error: 'Error in getting data from server, Please try again later'
9 | }
10 | };
11 | };
12 |
13 | angular.module('angularJsSeedApp')
14 | .factory('Messages', Constants)
15 | })(angular)
16 |
--------------------------------------------------------------------------------
/client/app/landing/landing.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | angular.module('angularJsSeedApp')
6 | .config(function($stateProvider) {
7 | $stateProvider
8 | .state('landing', {
9 | url: '/',
10 | templateUrl: 'app/landing/landing.html',
11 | controller: 'LandingCtrl',
12 | controllerAs: 'landing'
13 | });
14 | });
15 |
16 | })(angular)
17 |
--------------------------------------------------------------------------------
/client/components/footer/footer.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | angular.module('angularJsSeedApp')
6 | .directive('footer', function () {
7 | return {
8 | templateUrl: 'components/footer/footer.html',
9 | restrict: 'E',
10 | link: function (scope, element) {
11 | element.addClass('footer');
12 | }
13 | };
14 | });
15 |
16 | })(angular);
17 |
--------------------------------------------------------------------------------
/client/app/home/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | angular.module('angularJsSeedApp')
6 | .config(function($stateProvider) {
7 | $stateProvider
8 | .state('home', {
9 | url: '/home',
10 | templateUrl: 'app/home/home.html',
11 | controller: 'HomeCtrl',
12 | controllerAs: 'Home',
13 | authenticate: true
14 | })
15 | });
16 |
17 | })(angular)
18 |
--------------------------------------------------------------------------------
/client/app/home/home.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function homeCtrl(ModalService) {
6 | /**
7 | * Controller variables
8 | */
9 | var Home = this;
10 |
11 | /**
12 | *Show popup
13 | */
14 | Home.openPopUp = function (){
15 | ModalService.successPopup();
16 | }
17 | };
18 |
19 | angular.module('angularJsSeedApp')
20 | .controller('HomeCtrl', homeCtrl)
21 |
22 | })(angular)
23 |
--------------------------------------------------------------------------------
/e2e/main/main.po.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file uses the Page Object pattern to define the main page for tests
3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
4 | */
5 |
6 | 'use strict';
7 |
8 | var MainPage = function() {
9 | this.heroEl = element(by.css('.hero-unit'));
10 | this.h1El = this.heroEl.element(by.css('h1'));
11 | this.imgEl = this.heroEl.element(by.css('img'));
12 | };
13 |
14 | module.exports = new MainPage();
15 |
16 |
--------------------------------------------------------------------------------
/e2e/main/main.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Main View', function() {
4 | var page;
5 |
6 | beforeEach(function() {
7 | browser.get('/');
8 | page = require('./main.po');
9 | });
10 |
11 | it('should include jumbotron with correct data', function() {
12 | expect(page.h1El.getText()).toBe('\'Allo, \'Allo!');
13 | expect(page.imgEl.getAttribute('src')).toMatch(/assets\/images\/yeoman.png$/);
14 | expect(page.imgEl.getAttribute('alt')).toBe('I\'m Yeoman');
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/client/components/constants/constants.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by princesoni on 11/13/15.
3 | */
4 | 'use strict';
5 |
6 | (function (angular) {
7 |
8 | function constants() {
9 |
10 | return {
11 | //User roles
12 | roles: {
13 | BUSINESS_USER: 'businessUser',
14 | USER: 'user'
15 | },
16 | popup: {
17 | SUCCESS: 'SUCCESS',
18 | ERROR: 'ERROR'
19 | }
20 | }
21 | }
22 |
23 | //factory declaration
24 | angular.module('angularJsSeedApp')
25 | .factory('Constants', constants);
26 |
27 | })(angular);
28 |
--------------------------------------------------------------------------------
/client/components/header/header.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function header($scope, Auth) {
6 | var Header = this;
7 | Header.menu = [{
8 | 'title': 'Home',
9 | 'state': 'home'
10 | }];
11 |
12 | Header.isCollapsed = true;
13 | Header.isLoggedIn = Auth.isLoggedIn;
14 | Header.isAdmin = Auth.isAdmin;
15 | Header.getCurrentUser = Auth.getCurrentUser;
16 | }
17 |
18 | //controller declaration
19 | angular.module('angularJsSeedApp')
20 | .controller('HeaderCtrl', header);
21 |
22 | })(angular)
23 |
--------------------------------------------------------------------------------
/client/components/modal/modal.css:
--------------------------------------------------------------------------------
1 | .modal-primary .modal-header,
2 | .modal-info .modal-header,
3 | .modal-success .modal-header,
4 | .modal-warning .modal-header,
5 | .modal-danger .modal-header {
6 | color: #fff;
7 | border-radius: 5px 5px 0 0;
8 | }
9 | .modal-primary .modal-header {
10 | background: #428bca;
11 | }
12 | .modal-info .modal-header {
13 | background: #5bc0de;
14 | }
15 | .modal-success .modal-header {
16 | background: #5cb85c;
17 | }
18 | .modal-warning .modal-header {
19 | background: #f0ad4e;
20 | }
21 | .modal-danger .modal-header {
22 | background: #d9534f;
23 | }
24 |
--------------------------------------------------------------------------------
/client/components/modal/modal.controller.js:
--------------------------------------------------------------------------------
1 |
2 | 'use strict';
3 | (function (angular) {
4 |
5 | function ModalCtrl($modalInstance, $state, modalView, popupData, Constants, Messages, Helper, $timeout) {
6 | /**
7 | * Controller variable
8 | */
9 | var ctrl = this;
10 | ctrl.view = modalView;
11 | ctrl.popupData = popupData;
12 |
13 | /**
14 | * close modal
15 | * @param reload
16 | */
17 | ctrl.closeModal = function (reload) {
18 | $modalInstance.dismiss("cancel");
19 | };
20 | }
21 |
22 | angular.module('angularJsSeedApp')
23 | .controller('ModalCtrl', ModalCtrl);
24 | })(angular);
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-js-seed",
3 | "version": "0.0.0",
4 | "dependencies": {
5 | "angular": ">=1.3.*",
6 | "json3": "~3.3.1",
7 | "es5-shim": "~3.0.1",
8 | "bootstrap-sass-official": "~3.1.1",
9 | "bootstrap": "~3.1.1",
10 | "angular-resource": ">=1.2.*",
11 | "angular-cookies": ">=1.2.*",
12 | "angular-sanitize": ">=1.2.*",
13 | "angular-bootstrap": "~0.11.0",
14 | "font-awesome": ">=4.1.0",
15 | "lodash": "~2.4.1",
16 | "angular-ui-router": "~0.2.15",
17 | "angular-route": "^1.5.6"
18 | },
19 | "devDependencies": {
20 | "angular-mocks": ">=1.2.*",
21 | "angular-scenario": ">=1.2.*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/client/components/modal/views/success.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
9 |
Success
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/client/components/modal/views/error.html:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/client/components/loader/loader.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 | //Loader service
5 | function loaderService() {
6 | return {
7 | show: function (ele) {
8 | if (ele) {
9 | angular.element(ele).css('display', 'block');
10 | } else {
11 | angular.element('.loader').css('display', 'block');
12 | }
13 | },
14 |
15 | hide: function (ele) {
16 | if (ele) {
17 | angular.element(ele).css('display', 'none');
18 | } else {
19 | angular.element('.loader').css('display', 'none');
20 | }
21 | }
22 | }
23 | };
24 |
25 | angular.module('angularJsSeedApp')
26 | .factory('LoaderService', loaderService)
27 |
28 | })(angular);
29 |
--------------------------------------------------------------------------------
/client/components/api-services/user/user.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | angular.module('angularJsSeedApp')
6 | .factory('User', ['$resource', 'Config', function ($resource, Config) {
7 | return $resource(Config.getHost() + '/api/users/:id/:controller', {
8 | id: '@_id'
9 | },
10 | {
11 | get: {
12 | method: 'GET',
13 | params: {
14 | id:'me'
15 | }
16 | },
17 | forgotPassword: {
18 | method: 'POST',
19 | params: {
20 | id:'forgotPassword'
21 | }
22 | },
23 | changePassword: {
24 | method: 'PUT',
25 | params: {
26 | controller:'password'
27 | }
28 | }
29 | });
30 | }]);
31 |
32 | })(angular);
33 |
--------------------------------------------------------------------------------
/client/test/mocked.data.js:
--------------------------------------------------------------------------------
1 | angular.module('MockedJson', [])
2 | .value('AccountMocked', {
3 | data: {
4 | _id: 'lancomTest@cloud.com',
5 | groupId: 'groupId',
6 | adminUser: 'active',
7 | activeUsers: 'active',
8 | role: 'appAdmin',
9 | active: true,
10 | users: [{userId: '123', role: 'superAdmin'}],
11 | accounts: [{userId: '123', role: 'superAdmin'}],
12 | total:1
13 | }
14 | }
15 | )
16 | .value('UserMocked', {
17 | data: {
18 | _id: 'lancomTest@cloud.com',
19 | groupId: 'groupId',
20 | adminUser: 'active',
21 | activeUsers: 'active',
22 | role: 'appAdmin',
23 | active: true,
24 | users: [{userId: '123', role: 'superAdmin'}],
25 | total:1
26 | }
27 | }
28 | );
29 | 'use strict';
30 |
--------------------------------------------------------------------------------
/client/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "camelcase": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "immed": true,
10 | "latedef": true,
11 | "newcap": true,
12 | "noarg": true,
13 | "quotmark": "single",
14 | "undef": true,
15 | "unused": true,
16 | "strict": true,
17 | "trailing": true,
18 | "smarttabs": true,
19 | "globals": {
20 | "jQuery": true,
21 | "angular": true,
22 | "console": true,
23 | "$": true,
24 | "_": true,
25 | "moment": true,
26 | "describe": true,
27 | "beforeEach": true,
28 | "module": true,
29 | "inject": true,
30 | "it": true,
31 | "expect": true,
32 | "browser": true,
33 | "element": true,
34 | "by": true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/client/components/config/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by princesoni on 11/13/15.
3 | */
4 | 'use strict';
5 |
6 | (function (angular) {
7 | //configuration object
8 | function config() {
9 | var configuration = {
10 | ENV: 'DEVELOPMENT',
11 |
12 | ENVIRONMENTS: {
13 |
14 | STAGING: {
15 | URL: 'http://localhost:9000'
16 | },
17 |
18 | PRODUCTION: {
19 | URL: 'http://localhost:9000'
20 | },
21 |
22 | DEVELOPMENT: {
23 | URL: 'https://frozen-tundra-93174.herokuapp.com'
24 | }
25 | },
26 |
27 | getHost: function () {
28 | return this.ENVIRONMENTS[this.ENV] && this.ENVIRONMENTS[this.ENV].URL;
29 | }
30 |
31 | }
32 | return configuration;
33 | }
34 |
35 | //factory declaration
36 | angular.module('angularJsSeedApp')
37 | .factory('Config', config)
38 |
39 | })(angular);
40 |
--------------------------------------------------------------------------------
/client/app/account/changePassword/changePassword.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function changePassword(Auth) {
6 |
7 | var ChangePassword = this;
8 | ChangePassword.errors = {};
9 |
10 | ChangePassword.reset = function (form) {
11 | ChangePassword.submitted = true;
12 | if (form.$valid) {
13 | Auth.changePassword(ChangePassword.user.oldPassword, ChangePassword.user.newPassword)
14 | .then(function () {
15 | ChangePassword.message = 'Password successfully changed.';
16 | })
17 | .catch(function () {
18 | ChangePassword.errors.other = 'Incorrect password';
19 | ChangePassword.message = 'Unable to change password, Please check current password';
20 | });
21 | }
22 | };
23 | };
24 |
25 | angular.module('angularJsSeedApp')
26 | .controller('ChangePasswordCtrl', changePassword)
27 | })(angular);
28 |
--------------------------------------------------------------------------------
/client/app/account/signUp/signUp.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function signUpCtrl($scope, Auth, $state, $window) {
6 |
7 | /**
8 | * controller varibles
9 | */
10 | var SignUp = this;
11 | SignUp.user = {};
12 | SignUp.errors = {};
13 |
14 | /**
15 | * Signup user
16 | * @param form
17 | */
18 | SignUp.register = function (form) {
19 | SignUp.submitted = true;
20 |
21 | if (form.$valid) {
22 | Auth.createUser(SignUp.user)
23 | .then(function () {
24 | // Account created, redirect to home
25 | $state.go('home');
26 | })
27 | .catch(function (err) {
28 | err = err.data;
29 | $scope.errors = {};
30 |
31 | });
32 | }
33 | };
34 |
35 | }
36 |
37 | angular.module('angularJsSeedApp')
38 | .controller('SignUpCtrl', signUpCtrl);;
39 |
40 | })(angular)
41 |
--------------------------------------------------------------------------------
/client/app/account/login/login.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function loginCtrl($scope, Auth, $state, $window) {
6 |
7 | /**
8 | * controller variables
9 | */
10 | var Login = this;
11 | Login.user = {};
12 | Login.errors = {};
13 |
14 | /**
15 | *Login user
16 | * @param form
17 | */
18 | Login.login = function(form) {
19 | Login.submitted = true;
20 |
21 | if (form.$valid) {
22 | Auth.login({
23 | email: Login.user.email,
24 | password: Login.user.password
25 | })
26 | .then(function() {
27 | // Logged in, redirect to home
28 | $state.go('home');
29 | })
30 | .catch(function(error) {
31 | Login.errors.other = error.message;
32 | });
33 | }
34 | };
35 |
36 | }
37 |
38 | angular.module('angularJsSeedApp')
39 | .controller('LoginCtrl',loginCtrl);
40 | })(angular);
41 |
--------------------------------------------------------------------------------
/client/app/interceptor.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function(angular) {
4 |
5 | angular.module('angularJsSeedApp')
6 | .factory('authInterceptor', function ($rootScope, $q, $cookies, $injector) {
7 | var state;
8 | return {
9 | // Add authorization token to headers
10 | request: function(config) {
11 | config.headers = config.headers || {};
12 | if ($cookies && $cookies.get('token')) {
13 | config.headers.Authorization = 'Bearer ' + JSON.parse($cookies.get('token'));
14 | }
15 | return config;
16 | },
17 |
18 | // Intercept 401s and redirect you sto login
19 | responseError: function(response) {
20 | if (response.status === 401) {
21 | (state || (state = $injector.get('$state'))).go('login');
22 | // remove any stale tokens
23 | $cookies.remove('token');
24 | return $q.reject(response);
25 | }
26 | else {
27 | return $q.reject(response);
28 | }
29 | }
30 | };
31 |
32 | })
33 |
34 | })(angular);
35 |
--------------------------------------------------------------------------------
/client/components/util/helper.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by princesoni on 11/13/15.
3 | */
4 | 'use strict';
5 |
6 | /**
7 | * Helper service
8 | */
9 | (function (angular) {
10 | function Helper() {
11 | return {
12 |
13 | /**
14 | *
15 | * @param obj
16 | * @param keys
17 | * @returns {{}}
18 | */
19 | filterObject: function (obj, keys) {
20 | var result = {};
21 | for (var type in obj)
22 | if (keys.indexOf(type) > -1)
23 | result[type] = obj[type];
24 | return result;
25 | },
26 |
27 | /**
28 | *
29 | * @param text
30 | * @returns {*}
31 | */
32 | trim: function (text) {
33 | return text.replace(/\s+/, "")
34 | },
35 |
36 | /**
37 | *
38 | * @param arr
39 | * @returns {{}}
40 | */
41 | sortByKey: function (arr) {
42 | var ordered = {};
43 | Object.keys(arr).sort().forEach(function (key) {
44 | ordered[key] = arr[key];
45 | });
46 | return ordered
47 | }
48 | }
49 | }
50 |
51 | angular.module('angularJsSeedApp')
52 | .factory('Helper', Helper)
53 | })
54 | (angular);
55 |
--------------------------------------------------------------------------------
/client/components/header/header.html:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/client/app/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | angular.module('angularJsSeedApp', [
6 | 'ngCookies',
7 | 'ngResource',
8 | 'ngSanitize',
9 | 'ui.router',
10 | 'ui.bootstrap'
11 | ])
12 | .config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
13 | $urlRouterProvider
14 | .otherwise('/');
15 |
16 | $locationProvider.html5Mode(true);
17 | $httpProvider.interceptors.push('authInterceptor');
18 | })
19 | .run(['$rootScope', '$state', 'Auth', function ($rootScope, $state, Auth) {
20 | // Redirect to login if route requires auth and the user is not logged in
21 | $rootScope.$on('$stateChangeStart', function(event, next) {
22 | Auth.isLoggedInAsync(function(loggedIn) {
23 | //check for user authentication
24 | if (!loggedIn && next.authenticate) {
25 | event.preventDefault();
26 | $state.go('login');
27 | }
28 |
29 | //navigate to home if user is already authenticated
30 | if(loggedIn && (next.name === 'login' || next.name === 'landing')){
31 | event.preventDefault();
32 | $state.go('home');
33 | }
34 |
35 | if (next.authenticate && !loggedIn) {
36 | event.preventDefault();
37 | $state.go('login');
38 | }
39 | });
40 | });
41 | }]);
42 |
43 | })(angular);
44 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-angular-fullstack": {
3 | "insertRoutes": true,
4 | "registerRoutesFile": "server/routes.js",
5 | "routesNeedle": "// Insert routes below",
6 | "routesBase": "/api/",
7 | "pluralizeRoutes": true,
8 | "insertSockets": true,
9 | "registerSocketsFile": "server/config/socketio.js",
10 | "socketsNeedle": "// Insert sockets below",
11 | "filters": {
12 | "babel": false,
13 | "js": true,
14 | "html": true,
15 | "sass": true,
16 | "uirouter": true,
17 | "bootstrap": true,
18 | "uibootstrap": true,
19 | "mongoose": true,
20 | "auth": true
21 | }
22 | },
23 | "generator-ng-component": {
24 | "routeDirectory": "client/app/",
25 | "directiveDirectory": "client/app/",
26 | "filterDirectory": "client/app/",
27 | "serviceDirectory": "client/app/",
28 | "basePath": "client",
29 | "moduleName": "",
30 | "filters": [
31 | "uirouter"
32 | ],
33 | "extensions": [
34 | "js",
35 | "html",
36 | "scss"
37 | ],
38 | "directiveSimpleTemplates": "",
39 | "directiveComplexTemplates": "",
40 | "filterTemplates": "",
41 | "serviceTemplates": "",
42 | "factoryTemplates": "",
43 | "controllerTemplates": "",
44 | "decoratorTemplates": "",
45 | "providerTemplates": "",
46 | "routeTemplates": ""
47 | }
48 | }
--------------------------------------------------------------------------------
/client/app/account/changePassword/changePassword.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
37 |
--------------------------------------------------------------------------------
/client/app/account/forgotPassword/forgotPassword.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 |
5 | function forgotPassword(User, $state) {
6 |
7 | /**
8 | * Controller variables
9 | */
10 | var ForgotPassword = this;
11 | ForgotPassword.sent = false;
12 | ForgotPassword.posting = false;
13 | ForgotPassword.error = '';
14 | ForgotPassword.form = {
15 | email: ''
16 | };
17 | ForgotPassword.requestFailed = false;
18 | ForgotPassword.submitted = false;
19 |
20 | /**
21 | * Serves to submit a request for set password for provided user emailId.
22 | * @param form - formObject
23 | */
24 | ForgotPassword.forgotPassword = function (form) {
25 | ForgotPassword.submitted = true;
26 | if (form.$valid) {
27 | ForgotPassword.posting = true;
28 | ForgotPassword.requestFailed = false;
29 | User.forgotPassword({email: ForgotPassword.form.email}, function (data) {
30 | ForgotPassword.sent = true;
31 | ForgotPassword.goToLogin();
32 | }, function (err) {
33 | ForgotPassword.posting = false;
34 | ForgotPassword.error = err.code;
35 | ForgotPassword.requestFailed = true;
36 | })
37 | }
38 | };
39 |
40 | /**
41 | * navigate to login page
42 | */
43 | ForgotPassword.goToLogin = function () {
44 | $state.go('login');
45 | };
46 | };
47 |
48 | angular.module('angularJsSeedApp')
49 | .controller('ForgotPasswordCtrl', forgotPassword);
50 |
51 | })(angular);
52 |
--------------------------------------------------------------------------------
/client/app/account/forgotPassword/forgotPassword.html:
--------------------------------------------------------------------------------
1 |
2 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/client/components/modal/modal.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | (function (angular) {
3 | /**
4 | * Modal service
5 | * @param $modal
6 | * @param Constants
7 | * @param $timeout
8 | * @param $state
9 | * @returns {{successPopup: Function, errorPopup: Function}}
10 | * @constructor
11 | */
12 | function ModalService($modal, Constants,$timeout, $state) {
13 | function openModal(success, dismiss, view, data, sizeClass, controller) {
14 | controller = controller && controller + ' as popUp' || '';
15 | var modalInstance = $modal.open({
16 | templateUrl: 'components/modal/popUp.html',
17 | controller: controller || 'ModalCtrl as popUp',
18 | windowClass: 'modal-container',
19 | size: sizeClass,
20 | backdrop: "static",
21 | keyboard: false,
22 | resolve: {
23 | modalView: function () {
24 | return view;
25 | },
26 | popupData: function () {
27 | return data;
28 | }
29 | }
30 | });
31 | modalInstance.result.then(success, dismiss || angular.noop);
32 | }
33 |
34 | return {
35 | successPopup: function (data, successCallback, dismissCallback) {
36 | openModal(successCallback, dismissCallback, Constants.popup.SUCCESS, data, "md");
37 | },
38 | errorPopup: function (data, successCallback, dismissCallback) {
39 | openModal(successCallback, dismissCallback, Constants.popup.ERROR, data, "md");
40 | }
41 | }
42 | }
43 |
44 | angular.module("angularJsSeedApp")
45 | .factory("ModalService", ModalService);
46 | })(angular);
47 |
48 |
--------------------------------------------------------------------------------
/client/app/account/login/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
47 |
--------------------------------------------------------------------------------
/client/app/account/account.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function (angular) {
4 | angular.module('angularJsSeedApp')
5 | .config(function configuration($stateProvider) {
6 | $stateProvider
7 | .state('login', {
8 | url: '/login',
9 | templateUrl: 'app/account/login/login.html',
10 | controller: 'LoginCtrl',
11 | controllerAs: 'Login'
12 | })
13 | .state('logout', {
14 | url: '/logout?referrer',
15 | referrer: 'login',
16 | template: '',
17 | controller: function($state, Auth) {
18 | var referrer = $state.params.referrer || 'login';
19 | Auth.logout();
20 | $state.go(referrer);
21 | }
22 | })
23 | .state('signUp', {
24 | url: '/signup',
25 | templateUrl: 'app/account/signUp/signUp.html',
26 | controller: 'SignUpCtrl',
27 | controllerAs: 'SignUp'
28 | })
29 | .state('forgotPassword', {
30 | url: '/forgotpassword',
31 | templateUrl: 'app/account/forgotPassword/forgotPassword.html',
32 | controller: 'ForgotPasswordCtrl',
33 | controllerAs: 'ForgotPassword'
34 | })
35 | .state('changePassword', {
36 | url: '/changepassword',
37 | templateUrl: 'app/account/changePassword/changePassword.html',
38 | controller: 'ChangePasswordCtrl',
39 | controllerAs: 'ChangePassword',
40 | authenticate: true
41 | });
42 | })
43 | .run(function($rootScope) {
44 | $rootScope.$on('$stateChangeStart', function(event, next, nextParams, current) {
45 | if (next.name === 'logout' && current && current.name && !current.authenticate) {
46 | next.referrer = current.name;
47 | }
48 | });
49 | });
50 |
51 | })(angular)
52 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration
2 | // https://github.com/angular/protractor/blob/master/referenceConf.js
3 |
4 | 'use strict';
5 |
6 | exports.config = {
7 | // The timeout for each script run on the browser. This should be longer
8 | // than the maximum time your application needs to stabilize between tasks.
9 | allScriptsTimeout: 110000,
10 |
11 | // A base URL for your application under test. Calls to protractor.get()
12 | // with relative paths will be prepended with this.
13 | baseUrl: 'http://localhost:' + (process.env.PORT || '9000'),
14 |
15 | // If true, only chromedriver will be started, not a standalone selenium.
16 | // Tests for browsers other than chrome will not run.
17 | chromeOnly: false,
18 |
19 | // list of files / patterns to load in the browser
20 | specs: [
21 | 'e2e/**/*.spec.js'
22 | ],
23 |
24 | // Patterns to exclude.
25 | exclude: [],
26 |
27 | // ----- Capabilities to be passed to the webdriver instance ----
28 | //
29 | // For a full list of available capabilities, see
30 | // https://code.google.com/p/selenium/wiki/DesiredCapabilities
31 | // and
32 | // https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
33 | capabilities: {
34 | 'browserName': 'chrome'
35 | },
36 |
37 | // ----- The test framework -----
38 | //
39 | // Jasmine and Cucumber are fully supported as a test and assertion framework.
40 | // Mocha has limited beta support. You will need to include your own
41 | // assertion framework if working with mocha.
42 | framework: 'jasmine',
43 |
44 | // ----- Options to be passed to minijasminenode -----
45 | //
46 | // See the full list at https://github.com/juliemr/minijasminenode
47 | jasmineNodeOpts: {
48 | defaultTimeoutInterval: 30000
49 | }
50 | };
51 |
--------------------------------------------------------------------------------
/server/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Main application file
3 | */
4 |
5 | 'use strict';
6 |
7 | var express = require('express');
8 | var path = require('path');
9 | var favicon = require('serve-favicon');
10 | var cluster = require('cluster');
11 | var http = require('http');
12 | var clusterCount = 1;
13 | var env;
14 |
15 | // Change FRONT-END PORT here
16 | var PORT = 9000;
17 |
18 | // Change directory "public" here
19 | var FolderName = '../' + 'client';
20 |
21 | /*Command line arguments
22 | * Command node app.js [PORT] [PUBLIC-DIR-PATH]*/
23 | if (process.argv.length > 1) {
24 | env = process.argv[2] || 'development'
25 | PORT = (process.argv[3] && !isNaN(process.argv[3]) && +process.argv[3] ) || PORT;
26 | FolderName = process.argv[4] || FolderName;
27 | }
28 |
29 | /**
30 | * Cluster setting
31 | */
32 | if (cluster.isMaster) {
33 | var numReqs = 0;
34 |
35 | // Start workers and listen for messages containing notifyRequest
36 | var numCPUs = require('os').cpus().length;
37 | for (var i = 0; i < numCPUs; i++) {
38 | cluster.fork();
39 | }
40 |
41 | Object.keys(cluster.workers).forEach(function (id) {
42 | cluster.workers[id].on('message', function messageHandler(msg) {
43 | if (msg.cmd && msg.cmd == 'notifyRequest') {
44 | numReqs += 1;
45 | }
46 | });
47 | });
48 |
49 | } else {
50 | // Worker processes have a http server.
51 | // Setup server
52 | var app = express();
53 | var server = require('http').createServer(app);
54 |
55 | //app.use(favicon(path.join(__dirname, FolderName, 'favicon.ico')));
56 | if (env === 'development') {
57 | app.use(require('connect-livereload')());
58 | }
59 | app.use(favicon(path.join(__dirname, FolderName, 'favicon.ico')));
60 | app.use(express.static(path.join(__dirname, '../.tmp')));
61 | app.use(express.static(path.join(__dirname, FolderName)));
62 | app.set('appPath', path.join(__dirname, FolderName));
63 |
64 | // Insert routes below
65 | // All undefined asset or api routes should return a 404
66 | app.route('/:url(api|components|app|bower_components|assets)/*')
67 | .get(function (req, res) {
68 | res.send("Error 404");
69 | });
70 |
71 | // All other routes should redirect to the index.html
72 | app.route('/*')
73 | .get(function (req, res) {
74 | res.sendFile(app.get('appPath') + '/index.html');
75 | });
76 |
77 | // Start server
78 | server.listen(PORT, function () {
79 | console.log('Server Listening To PORT: %d ', PORT);
80 | clusterCount = clusterCount + 1;
81 | });
82 | }
83 |
84 | module.exports = app;
85 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // http://karma-runner.github.io/0.10/config/configuration-file.html
3 |
4 | module.exports = function(config) {
5 | config.set({
6 | // base path, that will be used to resolve files and exclude
7 | basePath: '',
8 |
9 | // testing framework to use (jasmine/mocha/qunit/...)
10 | frameworks: ['jasmine'],
11 |
12 | // list of files / patterns to load in the browser
13 | files: [
14 | 'client/bower_components/jquery/dist/jquery.js',
15 | 'client/bower_components/angular/angular.js',
16 | 'client/bower_components/angular-mocks/angular-mocks.js',
17 | 'client/bower_components/angular-resource/angular-resource.js',
18 | 'client/bower_components/angular-cookies/angular-cookies.js',
19 | 'client/bower_components/angular-sanitize/angular-sanitize.js',
20 | 'client/bower_components/angular-route/angular-route.js',
21 | 'client/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
22 | 'client/bower_components/lodash/dist/lodash.compat.js',
23 | 'client/bower_components/angular-ui-router/release/angular-ui-router.js',
24 | 'client/app/app.js',
25 | 'client/app/**/*.js',
26 | 'client/test/**/*.js',
27 | 'client/components/**/*.js',
28 | 'client/app/**/*.html',
29 | 'client/components/**/*.html'
30 | ],
31 |
32 | preprocessors: {
33 | '**/*.jade': 'ng-jade2js',
34 | '**/*.html': 'html2js'
35 | },
36 |
37 | plugins: [
38 | 'karma-phantomjs-launcher',
39 | 'karma-jasmine',
40 | 'karma-junit-reporter',
41 | 'karma-coverage'
42 | ],
43 |
44 | ngHtml2JsPreprocessor: {
45 | stripPrefix: 'client/'
46 | },
47 |
48 | ngJade2JsPreprocessor: {
49 | stripPrefix: 'client/'
50 | },
51 |
52 |
53 |
54 | // list of files / patterns to exclude
55 | exclude: [],
56 |
57 | // web server port
58 | port: 8080,
59 |
60 | // level of logging
61 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
62 | logLevel: config.LOG_INFO,
63 |
64 |
65 | // enable / disable watching file and executing tests whenever any file changes
66 | autoWatch: false,
67 |
68 |
69 | // Start these browsers, currently available:
70 | // - Chrome
71 | // - ChromeCanary
72 | // - Firefox
73 | // - Opera
74 | // - Safari (only Mac)
75 | // - PhantomJS
76 | // - IE (only Windows)
77 | browsers: ['PhantomJS'],
78 |
79 |
80 | // Continuous Integration mode
81 | // if true, it capture browsers, run tests and exit
82 | singleRun: false
83 | });
84 | };
85 |
--------------------------------------------------------------------------------
/client/test/account/forgotPassword/forgotPassword.controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Controller: ForgotCtrl', function () {
4 |
5 | // load the controller's module
6 | beforeEach(module('angularJsSeedApp'));
7 |
8 | var ForgotCtrl, scope, User, fakeState, q;
9 |
10 | // Initialize the controller and a mock scope
11 | beforeEach(inject(function ($controller, $rootScope, $q, $httpBackend) {
12 | scope = $rootScope.$new();
13 | q = $q;
14 | $httpBackend.whenGET('app/user/login/login.html').respond(200);
15 | User = jasmine.createSpyObj('User', ['setPasswordRequest']);
16 | fakeState = {
17 | go: function (url) {
18 | fakeState.redirect = url;
19 | }
20 | };
21 | ForgotCtrl = $controller('ForgotPasswordCtrl', {
22 | $scope: scope,
23 | $q: q,
24 | User: User,
25 | $state: fakeState
26 | });
27 | }));
28 |
29 | //This is success
30 | it('should have a ForgotPasswordCtrl controller', function () {
31 | expect('practiceRetrieverApp.ForgotPasswordCtrl').toBeDefined();
32 | });
33 | describe('Function:forgotPassword', function () {
34 | var fakeForm = {};
35 | it('password should be sent successfully when User.setPasswordRequest calls success', function () {
36 | User.setPasswordRequest.andCallFake(function (data, success, failure) {
37 | success({userData: {}});
38 | });
39 | ForgotCtrl.form.email = 'lancomTest@cloud.com';
40 | fakeForm.$valid = true;
41 | ForgotCtrl.forgotPassword(fakeForm);
42 | scope.$apply();
43 | expect(ForgotCtrl.sent).toBeTruthy();
44 | });
45 | it('should show error message and request failed when User.setPasswordRequest promise calls failure ', function () {
46 | User.setPasswordRequest.andCallFake(function (data, success, failure) {
47 | failure({data: 'Email id not correct'});
48 | });
49 | ForgotCtrl.form.email = 'lancomTest@cloud.com';
50 | fakeForm.$valid = true;
51 | ForgotCtrl.forgotPassword(fakeForm);
52 | scope.$apply();
53 | expect(ForgotCtrl.requestFailed).toBeTruthy();
54 | expect(ForgotCtrl.sent).toBeFalsy();
55 | });
56 | it('should not call User.setPasswordRequest function when submitted form is invalid', function () {
57 | fakeForm.$valid = false;
58 | ForgotCtrl.forgotPassword(fakeForm);
59 | scope.$apply();
60 | expect(ForgotCtrl.posting).toBeFalsy();
61 | expect(User.setPasswordRequest).not.toHaveBeenCalled();
62 | });
63 | });
64 | describe('Function:goToLogin', function () {
65 | it('should redirect to login when goToLogin function is called', function () {
66 | ForgotCtrl.goToLogin();
67 | scope.$apply();
68 | expect(fakeState.redirect).toEqual('login');
69 | });
70 | });
71 |
72 | });
73 |
--------------------------------------------------------------------------------
/client/app/app.scss:
--------------------------------------------------------------------------------
1 | $icon-font-path: "/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/";
2 | $fa-font-path: "/bower_components/font-awesome/fonts";
3 |
4 | @import 'bootstrap-sass-official/vendor/assets/stylesheets/bootstrap';
5 | @import 'font-awesome/scss/font-awesome';
6 |
7 | /**
8 | * App-wide Styles
9 | */
10 |
11 | /* navbar */
12 | #nav-main
13 | {
14 | background-color: #2c3e50;
15 | margin-bottom: 0;
16 | border:none;
17 | }
18 | #nav-main a.navbar-brand
19 | {
20 | font-size: 20px;
21 | font-weight: 500;
22 | color: #fff;
23 | }
24 | #nav-main li a
25 | {
26 | text-transform: uppercase;
27 | font-size: 16px;
28 | color: #fff;
29 | font-weight: bold;
30 | &:focus
31 | {
32 | background: transparent;
33 | color:#18bc9c;
34 | }
35 | &:hover
36 | {
37 | background: transparent;
38 | color:#18bc9c;
39 | }
40 | }
41 | #nav-main li.active a
42 | {
43 | background: #18bc9c;
44 | color: #fff;
45 | }
46 | .navbar-nav .admin-welcome
47 | {
48 | color: #18bc9c;
49 | }
50 | /* navbar */
51 |
52 | /* body */
53 | .jumbotron.jumbo-main
54 | {
55 | text-align: center;
56 | h1
57 | {
58 | text-align: center;
59 | color: #2c3e50;
60 | text-transform: uppercase;
61 | }
62 | }
63 | /* body */
64 |
65 | /* Login Form */
66 |
67 | .login-form
68 | {
69 | border: 1px solid #ddd;
70 | padding: 20px 20px 40px 20px;
71 | margin-top: 50px;
72 | background: #f5f5f5;
73 | h2
74 | {
75 | text-align: center;
76 | font-size: 20px;
77 | }
78 | .btn-login,.btn-register,.btn-danger,.btn-success
79 | {
80 | display: block;
81 | width: 100%;
82 | background-color: #47a447;
83 | border-color: #398439;
84 | color: #fff;
85 | border-radius: 0;
86 | height: 35px;
87 | line-height: 35px;
88 | padding: 0;
89 | margin-top: 15px;
90 | font-size: 14px;
91 | }
92 | .btn-register
93 | {
94 | background-color: #428bca;
95 | border-color: #357ebd;
96 | }
97 | .forgot-password {
98 | margin-top: 8px;
99 | display: block;
100 | }
101 | .btn-danger
102 | {
103 | background-color: #d9534f;
104 | border-color: #d43f3a;
105 | }
106 | }
107 | /* Login Form */
108 | /* footer */
109 | footer
110 | {
111 | position: absolute;
112 | bottom: 0;
113 | width: 100%;
114 | height: 60px;
115 | background-color: #233140;
116 | h3
117 | {
118 | margin: 0;
119 | text-align: center;
120 | color: #fff;
121 | font-size: 16px;
122 | line-height: 60px;
123 | }
124 | }
125 | /* footer */
126 | .browsehappy {
127 | margin: 0.2em 0;
128 | background: #ccc;
129 | color: #000;
130 | padding: 0.2em 0;
131 | }
132 |
133 | // Component styles are injected through grunt
134 | // injector
135 | // endinjector
136 |
--------------------------------------------------------------------------------
/client/app/account/signUp/signUp.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
69 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-js-seed",
3 | "description": "Seed project for angular js application",
4 | "version": "1.0.4",
5 | "main": "server/app.js",
6 | "dependencies": {
7 | "express": "~4.9.0",
8 | "serve-favicon": "~2.0.1"
9 | },
10 | "author": {
11 | "name": "Prince Soni",
12 | "email": "1989prince.soni@gmail.com"
13 | },
14 | "scripts": {
15 | "start": "node server/app.js",
16 | "test": "grunt test:client"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/princesoni1989/angular-js-seed.git"
21 | },
22 | "keywords": [
23 | "angular",
24 | "angular seed",
25 | "angular-js-seed",
26 | "angularjs",
27 | "angularseed",
28 | "seed"
29 | ],
30 | "license": "ISC",
31 | "bugs": {
32 | "url": "https://github.com/princesoni1989/angular-js-seed/issues"
33 | },
34 | "homepage": "https://github.com/princesoni1989/angular-js-seed#readme",
35 | "devDependencies": {
36 | "connect-livereload": "~0.4.0",
37 | "grunt": "~0.4.4",
38 | "grunt-angular-templates": "^0.5.4",
39 | "grunt-autoprefixer": "~0.7.2",
40 | "grunt-build-control": "~0.4.0",
41 | "grunt-concurrent": "~0.5.0",
42 | "grunt-contrib-clean": "~0.5.0",
43 | "grunt-contrib-concat": "~0.4.0",
44 | "grunt-contrib-copy": "~0.5.0",
45 | "grunt-contrib-cssmin": "~0.9.0",
46 | "grunt-contrib-htmlmin": "~0.2.0",
47 | "grunt-contrib-imagemin": "~0.7.1",
48 | "grunt-contrib-jshint": "~0.10.0",
49 | "grunt-contrib-sass": "^0.7.3",
50 | "grunt-contrib-uglify": "~0.4.0",
51 | "grunt-contrib-watch": "~0.6.1",
52 | "grunt-dom-munger": "^3.4.0",
53 | "grunt-env": "~0.4.1",
54 | "grunt-express-server": "~0.4.17",
55 | "grunt-google-cdn": "~0.4.0",
56 | "grunt-injector": "~0.5.4",
57 | "grunt-karma": "~0.8.2",
58 | "grunt-mocha-test": "~0.10.2",
59 | "grunt-newer": "~0.7.0",
60 | "grunt-ng-annotate": "^0.2.3",
61 | "grunt-node-inspector": "~0.1.5",
62 | "grunt-nodemon": "~0.2.0",
63 | "grunt-open": "~0.2.3",
64 | "grunt-protractor-runner": "^3.2.0",
65 | "grunt-protractor-webdriver": "^0.2.5",
66 | "grunt-rev": "~0.1.0",
67 | "grunt-svgmin": "~0.4.0",
68 | "grunt-usemin": "~2.1.1",
69 | "grunt-wiredep": "~1.8.0",
70 | "jit-grunt": "^0.5.0",
71 | "jshint-stylish": "~0.1.5",
72 | "karma": "~0.12.9",
73 | "karma-chrome-launcher": "~0.1.3",
74 | "karma-coffee-preprocessor": "~0.2.1",
75 | "karma-coverage": "^0.5.0",
76 | "karma-firefox-launcher": "~0.1.3",
77 | "karma-html2js-preprocessor": "~0.1.0",
78 | "karma-jade-preprocessor": "0.0.11",
79 | "karma-jasmine": "~0.1.5",
80 | "karma-ng-html2js-preprocessor": "~0.1.0",
81 | "karma-ng-jade2js-preprocessor": "^0.1.2",
82 | "karma-ng-scenario": "~0.1.0",
83 | "karma-phantomjs-launcher": "~0.2.0",
84 | "karma-requirejs": "~0.2.1",
85 | "karma-script-launcher": "~0.1.0",
86 | "open": "~0.0.4",
87 | "protractor": "^3.3.0",
88 | "requirejs": "~2.1.11",
89 | "should": "~3.3.1",
90 | "supertest": "~0.11.0",
91 | "time-grunt": "~0.3.1",
92 | "phantomjs": "^1.9.18"
93 | },
94 | "engines": {
95 | "node": ">=0.10.0"
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/client/test/home/home.controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Controller: LoginCtrl', function () {
4 | var LoginCtrl, q, rootScope, scope, fakeLocation, Auth, $state, fakeForm;
5 | beforeEach(module('angularJsSeedApp'));
6 | beforeEach(inject(function ($q, $controller, $rootScope, $httpBackend) {
7 | q = $q,
8 | rootScope = $rootScope,
9 | scope = rootScope.$new();
10 | $httpBackend.whenGET('app/user/login/login.html')
11 | .respond(200);
12 | Auth = jasmine.createSpyObj('Auth', ['login']);
13 | $state = jasmine.createSpyObj('$state', ['go']);
14 | $state.go.andCallFake(function (url) {
15 |
16 | });
17 | $state.params = {
18 | loginSuccess: false,
19 | sessionExpired: false
20 | };
21 | fakeForm = {
22 | '$valid': true
23 | };
24 |
25 | LoginCtrl = $controller('LoginCtrl', {
26 | $scope: scope,
27 | $q: q,
28 | Auth: Auth,
29 | $state: $state
30 | //$location: fakeLocation,
31 | //$routeParams: routeParams
32 | });
33 | rootScope.$digest();
34 | }
35 | ));
36 | //This is success
37 | it('should have a LoginCtrl controller', function () {
38 | expect('angularJsSeedApp.LoginCtrl').toBeDefined();
39 | });
40 |
41 | describe('Function:login', function () {
42 | it('should redirect to home Auth.login promise get resolved ', function () {
43 | Auth.login.andCallFake(function (data) {
44 | var deferred = q.defer();
45 | deferred.resolve({userData: {}});
46 | //deferred.$promise = deferred.promise;
47 | return deferred.promise;
48 | });
49 | LoginCtrl.user.email = 'lancomTest@cloud.com';
50 | LoginCtrl.user.password = 'lancomTest';
51 | LoginCtrl.login(fakeForm);
52 | scope.$apply();
53 | expect($state.go).toHaveBeenCalledWith('home');
54 | });
55 | it('should show error message when Auth.login promise get rejected with message "notActive"', function () {
56 | Auth.login.andCallFake(function (data) {
57 | var deferred = q.defer();
58 | deferred.reject({message: 'notActive'});
59 | return deferred.promise;
60 | });
61 | LoginCtrl.user.email = 'lancomTest@cloud.com';
62 | LoginCtrl.user.password = 'lancomTest';
63 | LoginCtrl.login(fakeForm);
64 | scope.$apply();
65 | expect(LoginCtrl.notActivated).toEqual(true);
66 | });
67 | it('should show error message when Auth.login promise get rejected ', function () {
68 | Auth.login.andCallFake(function (data) {
69 | var deferred = q.defer();
70 | deferred.reject({message: 'Authentication failure'});
71 | return deferred.promise;
72 | });
73 | LoginCtrl.user.email = 'lancomTest@cloud.com';
74 | LoginCtrl.user.password = 'lancomTest';
75 | LoginCtrl.login(fakeForm);
76 | scope.$apply();
77 | expect(LoginCtrl.errors.other).toEqual('Authentication failure');
78 | });
79 | });
80 | describe('Function:signUp', function () {
81 | it('should redirect to signUp when signUp is called ', function () {
82 | LoginCtrl.signUp();
83 | scope.$apply();
84 | expect($state.go).toHaveBeenCalledWith('signup');
85 | });
86 | });
87 | describe('Function:forgotPassword', function () {
88 | it('should redirect to forgotPassword when forgotPassword is called ', function () {
89 | LoginCtrl.forgotPassword();
90 | scope.$apply();
91 | expect($state.go).toHaveBeenCalledWith('forgotPassword');
92 | });
93 | });
94 | });
95 |
--------------------------------------------------------------------------------
/client/test/landing/landing.controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Controller: LoginCtrl', function () {
4 | var LoginCtrl, q, rootScope, scope, fakeLocation, Auth, $state, fakeForm;
5 | beforeEach(module('angularJsSeedApp'));
6 | beforeEach(inject(function ($q, $controller, $rootScope, $httpBackend) {
7 | q = $q,
8 | rootScope = $rootScope,
9 | scope = rootScope.$new();
10 | $httpBackend.whenGET('app/user/login/login.html')
11 | .respond(200);
12 | Auth = jasmine.createSpyObj('Auth', ['login']);
13 | $state = jasmine.createSpyObj('$state', ['go']);
14 | $state.go.andCallFake(function (url) {
15 |
16 | });
17 | $state.params = {
18 | loginSuccess: false,
19 | sessionExpired: false
20 | };
21 | fakeForm = {
22 | '$valid': true
23 | };
24 |
25 | LoginCtrl = $controller('LoginCtrl', {
26 | $scope: scope,
27 | $q: q,
28 | Auth: Auth,
29 | $state: $state
30 | //$location: fakeLocation,
31 | //$routeParams: routeParams
32 | });
33 | rootScope.$digest();
34 | }
35 | ));
36 | //This is success
37 | it('should have a LoginCtrl controller', function () {
38 | expect('angularJsSeedApp.LoginCtrl').toBeDefined();
39 | });
40 |
41 | describe('Function:login', function () {
42 | it('should redirect to home Auth.login promise get resolved ', function () {
43 | Auth.login.andCallFake(function (data) {
44 | var deferred = q.defer();
45 | deferred.resolve({userData: {}});
46 | //deferred.$promise = deferred.promise;
47 | return deferred.promise;
48 | });
49 | LoginCtrl.user.email = 'lancomTest@cloud.com';
50 | LoginCtrl.user.password = 'lancomTest';
51 | LoginCtrl.login(fakeForm);
52 | scope.$apply();
53 | expect($state.go).toHaveBeenCalledWith('home');
54 | });
55 | it('should show error message when Auth.login promise get rejected with message "notActive"', function () {
56 | Auth.login.andCallFake(function (data) {
57 | var deferred = q.defer();
58 | deferred.reject({message: 'notActive'});
59 | return deferred.promise;
60 | });
61 | LoginCtrl.user.email = 'lancomTest@cloud.com';
62 | LoginCtrl.user.password = 'lancomTest';
63 | LoginCtrl.login(fakeForm);
64 | scope.$apply();
65 | expect(LoginCtrl.notActivated).toEqual(true);
66 | });
67 | it('should show error message when Auth.login promise get rejected ', function () {
68 | Auth.login.andCallFake(function (data) {
69 | var deferred = q.defer();
70 | deferred.reject({message: 'Authentication failure'});
71 | return deferred.promise;
72 | });
73 | LoginCtrl.user.email = 'lancomTest@cloud.com';
74 | LoginCtrl.user.password = 'lancomTest';
75 | LoginCtrl.login(fakeForm);
76 | scope.$apply();
77 | expect(LoginCtrl.errors.other).toEqual('Authentication failure');
78 | });
79 | });
80 | describe('Function:signUp', function () {
81 | it('should redirect to signUp when signUp is called ', function () {
82 | LoginCtrl.signUp();
83 | scope.$apply();
84 | expect($state.go).toHaveBeenCalledWith('signup');
85 | });
86 | });
87 | describe('Function:forgotPassword', function () {
88 | it('should redirect to forgotPassword when forgotPassword is called ', function () {
89 | LoginCtrl.forgotPassword();
90 | scope.$apply();
91 | expect($state.go).toHaveBeenCalledWith('forgotPassword');
92 | });
93 | });
94 | });
95 |
--------------------------------------------------------------------------------
/client/test/account/login/login.controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Controller: LoginCtrl', function () {
4 | var LoginCtrl, q, rootScope, scope, fakeLocation, Auth, $state, fakeForm;
5 | beforeEach(module('angularJsSeedApp'));
6 |
7 | beforeEach(inject(function ($q, $controller, $rootScope, $httpBackend) {
8 | q = $q,
9 | rootScope = $rootScope,
10 | scope = rootScope.$new();
11 | $httpBackend.whenGET('app/account/login/login.html')
12 | .respond(200);
13 | Auth = jasmine.createSpyObj('Auth', ['login']);
14 | $state = jasmine.createSpyObj('$state', ['go']);
15 | $state.go.andCallFake(function (url) {
16 |
17 | });
18 | $state.params = {
19 | loginSuccess: false,
20 | sessionExpired: false
21 | };
22 | fakeForm = {
23 | '$valid': true
24 | };
25 |
26 | LoginCtrl = $controller('LoginCtrl', {
27 | $scope: scope,
28 | $q: q,
29 | Auth: Auth,
30 | $state: $state
31 | //$location: fakeLocation,
32 | //$routeParams: routeParams
33 | });
34 | rootScope.$digest();
35 |
36 | }
37 | ));
38 |
39 | //This is success
40 | it('should have a LoginCtrl controller', function () {
41 | console.log("LoginCtrl",LoginCtrl)
42 | //expect('angularJsSeedApp.LoginCtrl').toBeDefined();
43 | });
44 |
45 | xdescribe('Function:login', function () {
46 | it('should redirect to home Auth.login promise get resolved ', function () {
47 | Auth.login.andCallFake(function (data) {
48 | var deferred = q.defer();
49 | deferred.resolve({userData: {}});
50 | //deferred.$promise = deferred.promise;
51 | return deferred.promise;
52 | });
53 | LoginCtrl.user.email = 'lancomTest@cloud.com';
54 | LoginCtrl.user.password = 'lancomTest';
55 | LoginCtrl.login(fakeForm);
56 | scope.$apply();
57 | expect($state.go).toHaveBeenCalledWith('home');
58 | });
59 | it('should show error message when Auth.login promise get rejected with message "notActive"', function () {
60 | Auth.login.andCallFake(function (data) {
61 | var deferred = q.defer();
62 | deferred.reject({message: 'notActive'});
63 | return deferred.promise;
64 | });
65 | LoginCtrl.user.email = 'lancomTest@cloud.com';
66 | LoginCtrl.user.password = 'lancomTest';
67 | LoginCtrl.login(fakeForm);
68 | scope.$apply();
69 | expect(LoginCtrl.notActivated).toEqual(true);
70 | });
71 | it('should show error message when Auth.login promise get rejected ', function () {
72 | Auth.login.andCallFake(function (data) {
73 | var deferred = q.defer();
74 | deferred.reject({message: 'Authentication failure'});
75 | return deferred.promise;
76 | });
77 | LoginCtrl.user.email = 'lancomTest@cloud.com';
78 | LoginCtrl.user.password = 'lancomTest';
79 | LoginCtrl.login(fakeForm);
80 | scope.$apply();
81 | expect(LoginCtrl.errors.other).toEqual('Authentication failure');
82 | });
83 | });
84 | xdescribe('Function:signUp', function () {
85 | it('should redirect to signUp when signUp is called ', function () {
86 | LoginCtrl.signUp();
87 | scope.$apply();
88 | expect($state.go).toHaveBeenCalledWith('signup');
89 | });
90 | });
91 | xdescribe('Function:forgotPassword', function () {
92 | it('should redirect to forgotPassword when forgotPassword is called ', function () {
93 | LoginCtrl.forgotPassword();
94 | scope.$apply();
95 | expect($state.go).toHaveBeenCalledWith('forgotPassword');
96 | });
97 | });
98 | });
99 |
--------------------------------------------------------------------------------
/client/favicon.ico:
--------------------------------------------------------------------------------
1 | � ( @ -2Op"=p�Jt��Jt��b���������������������������������������������������b���Jt��Jt��"=p�Op-2 O`O�O�O�O�O�O�O�$\�Jt��������������v���v���������������Jt��$\�O�O�O�O�O�O�O�O` O�O�O�O�O�O�O�O�O�O� ;n�s���>���>���>���>���s��� ;n�O�O�O�O�O�O�O�O�O�O� O`O�O�O�O�O�O�O�O�O�O�$\�]���^n��^n��]���$\�O�O�O�O�O�O�O�O�O�O�O` O�O�O�O�O�O�O�O�O�O�O�n�* ��* ��n�O�O�O�O�O�O�O�O�O�O�O� O�O�O�O�O�O�O�O�O�O�O�5>Y�5>Y�O�O�O�O�O�O�O�O�O�O�O� -2O�O�O�O�O�O�O�O�O�O�&6e�&6e�O�O�O�O�O�O�O�O�O�O�-2 5r�4���E���$\�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�$\�E���4���5r� 5r�E���M���M���v���0\��O�O�O�O�O�O�O�$\�$\�O�O�O�O�O�O�O�0\��v���M���M���E���5r� )��p&��p��&��������������b���Jt��Jt��Jt��0\��#i��.r��.r��#i��0\��Jt��Jt��Jt��b���������������&��p��&��)��p 4���&��-���_������������������]���]�������7���p�����������p���7�������]���]�������������������_��-���-���4��� qֈp��p��p����������������������p���7���#i��p�����������p���#i��7���p�����������������������p��&��-���qֈ 8��(p��p��I���v���v���]���7���n���v���p���#i��]���v���v���]���#i��p���v���n���7���]���v���v���I���-���-���8��( ;��`-���M���7���7���7���.r��R��E��R��E��7���7���7���7���E��R��E��R��.r��7���7���7���M���M���;��` ���������������������������z ���������������������������
2 | � ���
3 | �
9�
9�
9�
9�
9�
9�
9�
9�
4 | �n�n�
5 | �
9�
9�
9�
9�
9�
9�
9�
9�
6 | ���� * �x* ��* ��* ��* ��* ��* ��* ��n�&