├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── package.json
├── release
├── visor.js
└── visor.min.js
├── sample
├── lib
│ ├── angular-cookies.js
│ ├── angular-route.js
│ ├── angular-ui-router.js
│ ├── angular.js
│ ├── bootstrap.css
│ └── style.css
├── ng-route
│ ├── app
│ │ ├── access_denied.html
│ │ ├── admin.html
│ │ ├── app.js
│ │ ├── home.html
│ │ ├── login.html
│ │ └── private.html
│ └── index.html
└── ui-router
│ ├── app
│ ├── access_denied.html
│ ├── admin.html
│ ├── app.js
│ ├── home.html
│ ├── login.html
│ └── private.html
│ └── index.html
├── src
├── delayLocationChange.js
├── visor.allowed.js
├── visor.js
├── visor.ngRoute.js
├── visor.permissions.js
└── visor.ui-router.js
└── test
├── karma.conf.js
└── unit
├── delayLocationChange.spec.js
├── visor.allowed.spec.js
├── visor.ngRoute.spec.js
├── visor.permissions.spec.js
├── visor.spec.js
└── visor.ui-router.spec.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 | [*.js]
3 | charset = utf-8
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line =crlf
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | bower_components/
3 | build/
4 | .idea
5 | *.iml
6 | site/
7 | .grunt
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 0.10
4 |
5 | install:
6 | - npm install
7 | - npm run bower
8 | script:
9 | - npm test
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ### 0.1.2 (2015-12-07)
3 |
4 |
5 | #### Bug Fixes
6 |
7 | * **visor:** next parameter now overrides existing parameters ([b0c89109](https://github.com/illniyar/visor/commit/b0c89109), closes [#14](https://github.com/illniyar/visor/issues/14))
8 |
9 |
10 | #### Features
11 |
12 | * **visor:** allow changing next parameter name ([04d5d5d0](https://github.com/illniyar/visor/commit/04d5d5d0))
13 |
14 |
15 |
16 | ### 0.1.0 (2015-07-08)
17 |
18 |
19 | #### Bug Fixes
20 |
21 | * **ui-router:** state inheritance with dot notation does work with two levels of inheritance ([b7b05d5fce7dafd9f1047dc1e01ec2f4fd483ed5](https://github.com/illniyar/visor/commit/b7b05d5fce7dafd9f1047dc1e01ec2f4fd483ed5))
22 |
23 | #### Features
24 | * **visor.allowed:** add directives to add/remove classes from an element based on route restriction ([84f443bda058a6a950470899cd1331342ae05c69](https://github.com/illniyar/visor/commit/84f443bda058a6a950470899cd1331342ae05c69))
25 |
26 |
27 | ### 0.0.6 (2015-06-17)
28 |
29 |
30 | #### Bug Fixes
31 |
32 | * **ui-router:** send correct next parameter when visiting a page using $state.go ([f2201a8d](https://github.com/illniyar/visor/commit/f2201a8d), closes [#5](https://github.com/illniyar/visor/issues/5))
33 |
34 |
35 | ### 0.0.5 (2015-06-17)
36 |
37 |
38 | #### Bug Fixes
39 |
40 | * **ui-router:** fixed issue with next-url not being added properly with 1.3.0 . ([8bf3c906](https://github.com/illniyar/visor/commit/8bf3c906))
41 |
42 |
43 |
44 |
45 | ### 0.0.4 (2015-06-17)
46 |
47 |
48 | #### Bug Fixes
49 | * **authentication:** fix for arcane circular dependency injection bug. ([d03e6f10](https://github.com/illniyar/visor/commit/d03e6f10))
50 | * **ie8 support:** visor was not IE8 compatible due to using promise.finally directly. Issue #1 ([82877135](https://github.com/illniyar/visor/commit/82877135))
51 |
52 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | require('load-grunt-tasks')(grunt);
3 | grunt.initConfig({
4 | module_name: 'visor',
5 | pkg: grunt.file.readJSON('package.json'),
6 | builddir: 'build',
7 | releasedir: 'release',
8 | sitedir: 'site',
9 | meta: {
10 | banner: '/**<%= module_name %>\n' +
11 | '* <%= pkg.description %>\n' +
12 | '* @version v<%= pkg.version %>\n' +
13 | '* @link <%= pkg.homepage %>\n' +
14 | '* @license MIT License, http://www.opensource.org/licenses/MIT\n' +
15 | '*/\n'
16 | },
17 | clean: {
18 | dist: ['<%= builddir %>', '<%=sitedir %>'],
19 | 'gh-pages': ['.grunt']
20 | },
21 | concat: {
22 | options: {
23 | banner: '<%=meta.banner\n\n%>' +
24 | 'if (typeof module !== \'undefined\' && typeof exports !== \'undefined\' && module.exports === exports){\n' +
25 | ' module.exports = \'visor\';\n' +
26 | '}\n\n' +
27 | '(function (window, angular, undefined) {\n',
28 | footer: '})(window, window.angular);'
29 | },
30 | build: {
31 | src: 'src/*.js',
32 | dest: '<%= builddir %>/<%= module_name %>.js'
33 | }
34 | },
35 | uglify: {
36 | options: {
37 | banner: '<%= meta.banner %>\n'
38 | },
39 | build: {
40 | files: {
41 | '<%= builddir %>/<%= module_name %>.min.js': ['', '<%= concat.build.dest %>']
42 | }
43 | }
44 | },
45 | connect: {
46 | server: {},
47 | sample: {
48 | options: {
49 | port: 5555,
50 | keepalive: true
51 | }
52 | }
53 | },
54 | ngdocs: {
55 | all: ['src/**/*.js'],
56 | options: {
57 | dest: 'site/docs',
58 | html5Mode: false
59 | }
60 | },
61 | 'gh-pages': {
62 | options: {
63 | base: '<%=sitedir%>'
64 | },
65 | src: ['**']
66 | },
67 | copy: {
68 | release: {
69 | files: [{
70 | expand: true,
71 | src: ['visor.js', 'visor.min.js'],
72 | cwd: '<%=builddir%>/',
73 | dest: '<%=releasedir%>/'
74 | },
75 | {src: 'bower_components/angular/angular.js',
76 | dest:'sample/lib/angular.js'},
77 | {src: 'bower_components/angular-ui-router/release/angular-ui-router.js',
78 | dest:'sample/lib/angular-ui-router.js'},
79 | {src: 'bower_components/angular-route/angular-route.js',
80 | dest:'sample/lib/angular-route.js'},
81 | {src: 'bower_components/angular-cookies/angular-cookies.js',
82 | dest:'sample/lib/angular-cookies.js'}]
83 | },
84 | site: {
85 | files: [
86 | {expand: true, src: '<%=releasedir%>/**', dest: '<%=sitedir%>'},
87 | {expand: true, src: 'README.md', dest: '<%=sitedir%>'},
88 | {expand: true, src: 'sample/**', dest: '<%=sitedir%>'}]
89 | }
90 | },
91 | changelog: {
92 | options: {
93 | preset: 'angular',
94 | file: 'CHANGELOG.md',
95 | app_name: 'Visor'
96 | }
97 | },
98 | release: {
99 | options: {
100 | file: 'package.json',
101 | additionalFiles: 'bower.json',
102 | tagName: 'v<%= version %>',
103 | commitMessage: 'release <%= version %>',
104 | tagMessage: 'Version <%= version %>',
105 | beforeRelease: ['changelog']
106 | }
107 | },
108 | gitadd: {
109 | release: {
110 | files: {
111 | src: ['package.json', 'bower.json', 'CHANGELOG.md','release/visor.js','release/visor.min.js']
112 | }
113 | }
114 | },
115 | gitcommit: {
116 | master: {
117 | options: {
118 | message: 'Publish version <%= pkg.version %>'
119 | }
120 | }
121 | },
122 | gitpush: {
123 | origin: {
124 | options: {
125 | remote: 'origin',
126 | tags: true
127 | }
128 | },
129 | },
130 | gittag: {
131 | release: {
132 | options: {
133 | tag: 'v<%= pkg.version %>',
134 | annotated: true,
135 | message: 'version <%= pkg.version %>'
136 | }
137 | }
138 | },
139 | bumpup: {
140 | files: ['package.json', 'bower.json'],
141 | options: {
142 | updateProps: {
143 | pkg: 'package.json'
144 | }
145 | }
146 | }
147 | });
148 |
149 | grunt.registerTask('npm-publish', 'publish to npm.', function () {
150 | var npm = require('npm');
151 | var done = this.async();
152 | grunt.log.writeln('Publishing to NPM');
153 | npm.load(function () {
154 | npm.commands.publish(['.'], function (e) {
155 | if (e) {
156 | grunt.log.errorln(e);
157 | done(false);
158 | } else {
159 | grunt.log.writeln('Publish success');
160 | done();
161 | }
162 | })
163 | })
164 |
165 | });
166 | grunt.registerTask('build', 'Perform a normal build', ['concat', 'uglify']);
167 | grunt.registerTask('dist', 'Perform a clean build', ['clean', 'build', 'copy:release']);
168 | grunt.registerTask('site', 'Build and create site', ['dist', 'copy:site', 'ngdocs:all']);
169 | grunt.registerTask('build-gh-pages', 'Build, create site and push to gh-pages', ['gh-pages', 'clean:gh-pages']);
170 | grunt.registerTask('push-to-git', 'Add, commit, create tag and push to git', ['gitadd:release', 'gitcommit:master', 'gittag:release', 'gitpush:origin']);
171 | grunt.registerTask('publish', 'Builds and publishes to all relevent repositories',
172 | ['bumpup:patch', 'site', 'changelog', 'push-to-git', 'npm-publish','build-gh-pages'])
173 | }
174 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Illniyar
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Visor
2 |
3 | ## Authentication and authorization library for angular.js [](https://travis-ci.org/alonbardavid/visor)[](https://gemnasium.com/Illniyar/visor)
4 | ---
5 |
6 | Visor is an authentication and authorization framework for [AngularJS](http://angularjs.org).
7 | It provides a convenient way to authenticate on startup and define which routes are accessible to whom.
8 | Visor works with both ngRoute and ui-router.
9 |
10 | ## Quick start
11 |
12 | **Get Visor**:
13 | - download the [release](http://alonbardavid.github.io/visor/release/visor.js) (or [minified](http://alonbardavid.github.io/visor/release/visor.min.js))
14 | - via **[Bower](http://bower.io/)**: by running `$ bower install visor` from your console
15 | - via **[NPM](https://www.npmjs.com/package/angular-visor)**: by running `$ npm install --save angular-visor` from your console
16 |
17 | **Sample apps**:
18 | - A sample app using ui-router can be found [here](http://alonbardavid.github.io/visor/sample/ui-router) ([source](https://github.com/alonbardavid/visor/tree/master/sample/ui-router))
19 | - A sample app using ng-route can be found [here](http://alonbardavid.github.io/visor/sample/ng-route) ([source](https://github.com/alonbardavid/visor/tree/master/sample/ng-route))
20 |
21 | **API documentation**:
22 | - [API docs](http://alonbardavid.github.io/visor/docs)
23 |
24 | ###Authenticate with visor:
25 |
26 |
27 | ```
28 | angular.module("yourModule",["visor","ngRoute"]).
29 | configure(function(visorProvider,$routeProvider){
30 | visorProvider.authenticate = function($http){
31 | return $http.get().then(function(res){return res.data;}) //returns user
32 | };
33 | $routeProvider.when("/private",{
34 | restrict: function(user){ return user && user.can_see_private}
35 | })
36 | });
37 | ```
38 |
39 | ---
40 |
41 | ## Overview and Features
42 |
43 | Visor provides two main features:
44 |
45 | **Authentication**:
46 | * Visor allows you to stop routing until an authentication request is made.
47 | * Visor guarantees that authentication info is available (via visor.authInfo) before any restricted route is accessed.
48 | * If a client is not authenticated and tries to access an authenticated only route, it will be redirected to a designated login route.
49 | * After an unauthenticated client logsin/signsup, Visor makes sure to redirect the user back to the orignal route requested.
50 |
51 | **Authorization**:
52 | * Visor works with both ngRoute and ui-router, and allows to idiomatically restrict access to routes in either modules.
53 | * Unauthorized users are sent to a dedicated "access denied" route.
54 | * Restrictions are simple functions defined on routes/states which can access the user's authentication info.
55 |
56 | ---
57 |
58 | ## Usage
59 |
60 | ###Setting up the authenticate method
61 |
62 | Visor requires that you define an authentication method that runs before restricted routes are accessed.
63 | Visor exposes an authenticate method in it's provider:
64 |
65 | ```
66 | angular.module("yourModule",["visor"]).
67 | configure(function(visorProvider,$routeProvider){
68 | visorProvider.authenticate = function($http){
69 | return $http.get().then(function(res){return res.data;})
70 | };
71 | });
72 | ```
73 | The authenticate method is dependency injected, and needs to return a promise.
74 | The result from a successful promise will be sent to future restrict functions.
75 |
76 | * By default Visor authenticates when the page is loaded even if a non restricted route is accessed,
77 | you can instruct Visor to only authenticate when a restricted route is accessed by setting the `visorProvider.authenticateOnStartup" flag.
78 |
79 | ###Defining restrictions on routes
80 |
81 | To define certain routes to be restricted to certain users, Visor requires a "restrict" attribute to exist inside the route or state.
82 | That function will be called with the value returned from the `authenticate` promise and should return a boolean indicating if the routing should continue.
83 | If a user was not authenticated the restrict function will be called with no values.
84 |
85 | #### ngRoute:
86 |
87 | ```
88 | angular.module("yourModule",["ngRoute"]).
89 | configure(function($routeProvider){
90 | $routeProvider.when("/private",{ // will only be shown to users that have `can_see_private`
91 | restrict: function(auth){ return auth && auth.can_see_private}
92 | })
93 | .when("/only_not_authenticated",{ // will only be shown to users who are not authenticated
94 | restrict: function(auth){ return auth === undefined}
95 | })
96 | .when("/public",{}); // will be shown to any user
97 | });
98 | ```
99 |
100 | #### ui-router:
101 | ```
102 | angular.module("yourModule",["ui.router"]).
103 | configure(function($stateProvider){
104 | $stateProvider.state("private",{ // will only be shown to users that have `can_see_private`
105 | restrict: function(auth){ return auth && auth.can_see_private}
106 | })
107 | .state("only_not_authenticated",{ // will only be shown to users who are not authenticated
108 | restrict: function(auth){ return auth === undefined}
109 | })
110 | .state("public",{}); // will be shown to any user
111 | });
112 | ```
113 |
114 | **Visor also respects restrictions in parent states.**
115 | ```
116 | angular.module("yourModule",["ui.router"]).
117 | configure(function($stateProvider){
118 | $stateProvider.state("private",{ // will only be shown to users that have `can_see_private`
119 | restrict: function(auth){ return auth && auth.can_see_private}
120 | })
121 | .state("only_not_authenticated",{ // will only be shown to users that have `can_see_private`
122 | parent:"private"
123 | })
124 | .state("admin",{ // will only be shown to users who have both `can_see_private` and `is_admin`
125 | parent:"private",
126 | restrict: function(auth){ return auth && auth.is_admin}
127 | });
128 | });
129 | ```
130 |
131 | **Visor provides two default restriction methods as constants**:
132 | * `authenticatedOnly` - only users who are authenticated can see the route
133 | * `notForAuthenticated` - only users who aren't authenticated can see the route
134 |
135 | ```
136 | angular.module("yourModule",["ngRoute"]).
137 | configure(function($routeProvider,authenticatedOnly,notForAuthenticated){
138 | $routeProvider.when("/private",{ // will only be shown to users that are authenticated
139 | restrict: authenticatedOnly
140 | })
141 | .when("/only_not_authenticated",{ // will only be shown to users who are not authenticated
142 | restrict: notForAuthenticated
143 | })
144 | .when("/public",{}); // will be shown to any user
145 | });
146 | ```
147 |
148 | ### Configuring actions on events
149 |
150 | **Visor defines the following situations that can be overriden:**
151 | * An unauthenticated user tries to access a restricted route.
152 | * By default Visor will redirect to `/login' path.
153 | * The path can be overriden in `visorProvider.loginRoute`
154 | * The action taken when such an event occurs can be overriden in `visorProvider.doOnNotAuthenticated`
155 | * Visor adds a `next` parameter to the redirect to allow returning to the original path after a successful login.
156 | * You can instruct Visor to not add the `next` parameter by settings the `visorProvider.shouldAddNext` flag.
157 |
158 | * An authenticated user tries to access a restricted route.
159 | * By default Visor will redirect to `/access_denied' path.
160 | * The path can be overriden in `visorProvider.notAuthorizedRoute`
161 | * The action taken when such an event occurs can be overriden in `visorProvider.doOnNotAuthorized`
162 |
163 | * When a user is manually logged in.
164 | * By default if a `next` parameter exists in the url Visor will redirect to that path otherwise it'll redirect to `/' path.
165 | * The default path if no `next` is provided can be overriden in `visorProvider.homeRoute`
166 | * The action taken when such an event occurs can be overriden in `visorProvider.doAfterManualAuthentication`
167 |
168 | ###Login and Signup
169 | Visor needs to be notified when a user logs in to the application (as opposed to already being authenticated) in order for restrictions to work.
170 | You inform visor when a user logs in by calling `visor.setAuthenticated(authInfo)`.
171 | The value sent to `visor.isAuthenticated` to be the same as the value returned in the `authenticate` promise.
172 |
173 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "visor",
3 | "description": "Angular authentication and authorization library",
4 | "version": "0.1.2",
5 | "homepage": "https://github.com/illniyar/visor",
6 | "main": "./release/visor.js",
7 | "dependencies": {
8 | "angular": ">= 1.2.0"
9 | },
10 | "devDependencies": {
11 | "angular-ui-router": ">= 0.2.13",
12 | "angular-mocks": ">= 1.2.0",
13 | "angular-route": ">= 1.2.0",
14 | "angular-cookies": ">= 1.2.0"
15 | },
16 | "ignore": [
17 | "**/.*",
18 | "node_modules",
19 | "bower_components",
20 | "package.json",
21 | "Gruntfile.js",
22 | "test",
23 | "build",
24 | "sample"
25 | ]
26 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-visor",
3 | "author": "Illniyar",
4 | "version": "0.1.2",
5 | "main": "release/visor.js",
6 | "description": "Angular authentication and authorization library",
7 | "repository": "https://github.com/illniyar/visor.git",
8 | "homepage": "https://github.com/illniyar/visor.git",
9 | "devDependencies": {
10 | "bower": "~1.3.3",
11 | "grunt": "~0.4.1",
12 | "grunt-bumpup": "^0.6.2",
13 | "grunt-contrib-clean": "~0.5.0",
14 | "grunt-contrib-concat": "~0.3.0",
15 | "grunt-contrib-connect": "~0.7.1",
16 | "grunt-contrib-copy": "~0.5.0",
17 | "grunt-contrib-uglify": "~0.4.0",
18 | "grunt-conventional-changelog": "^1.2.2",
19 | "grunt-gh-pages": "~0.9.1",
20 | "grunt-git": "^0.3.5",
21 | "grunt-ngdocs": "~0.1.7",
22 | "karma": "~0.12",
23 | "karma-chrome-launcher": "~0.1",
24 | "karma-cli": "0.0.4",
25 | "karma-jasmine": "~0.2.0",
26 | "karma-phantomjs-launcher": "~0.1.4",
27 | "karma-spec-reporter": "0.0.12",
28 | "load-grunt-tasks": "~0.4.0",
29 | "npm": "^2.11.3"
30 | },
31 | "licenses": [
32 | {
33 | "type": "MIT",
34 | "url": "https://github.com/angular-ui/ui-router/blob/master/LICENSE"
35 | }
36 | ],
37 | "scripts": {
38 | "bower": "bower install",
39 | "test": "karma start test/karma.conf.js"
40 | },
41 | "dependencies": {
42 | "angular": ">= 1.2.0"
43 | }
44 | }
--------------------------------------------------------------------------------
/release/visor.min.js:
--------------------------------------------------------------------------------
1 | /**visor
2 | * Angular authentication and authorization library
3 | * @version v0.1.2
4 | * @link https://github.com/illniyar/visor.git
5 | * @license MIT License, http://www.opensource.org/licenses/MIT
6 | */
7 |
8 | "undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="visor"),function(a,b,c){!function(){"use strict";b.module("delayLocationChange",[]).service("delayLocationChange",["$rootScope","$q","$timeout","$location","$injector",function(a,b,c,d,e){function f(){m--,o&&0>=m&&g()}function g(){d.absUrl()===i?a.$broadcast("$locationChangeSuccess",i,j):d.url(k)}function h(a){m++,a["finally"](f)}var i,j,k,l=function(a){a.then?h(a):o?h(e.invoke(fn)):n.push(a)},m=0,n=[],o=!1,p=a.$on("$locationChangeStart",function(a,b,g){o=!0,k=d.url(),p(),a.preventDefault(),n.forEach(function(a){h(e.invoke(a))}),0!==m||i||(m++,c(f,1)),i=b,j=g});return l}])}(),function(){"use strict";b.module("visor.allowed",["visor.permissions"]).directive("showIfAllowed",["visorPermissions","$animate",function(a,b){return{restrict:"A",link:function(c,d,e){function f(c){var e=a.checkPermissionsForRoute(c);b[e?"removeClass":"addClass"](d,"ng-hide",{tempClasses:"ng-hide-animate"})}var g=a.notifyOnCacheClear(function(){f(e.showIfAllowed)});e.$observe("showIfAllowed",f),c.$on("$destroy",g)}}}]).directive("classIfRestricted",["visorPermissions","$animate",function(a,b){return{restrict:"A",link:function(c,d,e){function f(c){var f=a.checkPermissionsForRoute(c);b[f?"removeClass":"addClass"](d,e.restrictedClass||"visor-restricted")}var g=a.notifyOnCacheClear(function(){f(e.classIfRestricted)});e.$observe("classIfRestricted",f),c.$on("$destroy",g)}}}])}(),function(){"use strict";b.module("visor",["visor.permissions","visor.ui-router","visor.ngRoute","delayLocationChange","visor.allowed"]).constant("authenticatedOnly",function(a){return!!a}).constant("notForAuthenticated",function(a){return a===c}).provider("visor",[function(){var a=this;a.authenticateOnStartup=!0,a.loginRoute="/login",a.homeRoute="/",a.notAuthorizedRoute="/access_denied",a.shouldAddNext=!0,a.nextParameterName="next",a.authenticate=function(){throw new Error("visorProvider.authenticate must be defined to use visor")},a.doOnNotAuthenticated=["$location","restrictedUrl",function(b,c){b.url(a.loginRoute),a.shouldAddNext&&b.search(a.nextParameterName,c)}],a.doAfterManualAuthentication=["$location",function(b){b.url(b.search()[a.nextParameterName]||a.homeRoute)}],a.doOnNotAuthorized=["$location",function(b){b.url(a.notAuthorizedRoute)}],this.$get=["$injector","$q","$rootScope","$location","visorPermissions",function(b,d,e,f,g){function h(a){k.authData=a,g.invokeParameters=[k.authData],g.clearPermissionCache()}function i(){k.authData=c,g.invokeParameters=[],g.clearPermissionCache()}var j=!1,k={authenticate:function(c){if(j&&!c)return j;var e=d.defer();return j=e.promise,b.invoke(a.authenticate).then(h,i)["finally"](function(){e.resolve(k.authData)}),e.promise},setAuthenticated:function(c){h(c),j=d.when(c),b.invoke(a.doAfterManualAuthentication,null,{authData:c})},isAuthenticated:function(){return!!k.authData},onNotAllowed:function(c){k.isAuthenticated()?b.invoke(a.doOnNotAuthorized,null,{restrictedUrl:c}):b.invoke(a.doOnNotAuthenticated,null,{restrictedUrl:c})},setUnauthenticated:function(){i()},config:a};return k}]}]).run(["visor","delayLocationChange",function(a,b){a.config.authenticateOnStartup&&b(a.authenticate())}]).config(["visorPermissionsProvider",function(a){a.doBeforeFirstCheck.push(["visor",function(a){return a.authenticate()}]),a.onNotAllowed=["visor","restrictedUrl",function(a,b){a.onNotAllowed(b)}]}])}(),function(){b.module("visor.ngRoute",["visor.permissions"]).run(["$rootScope","visorPermissions","$injector",function(a,b,c){var d=!1,e=null;try{e=c.get("$route"),d=!0}catch(f){}d&&(b.getRoute=function(a){for(var b in e.routes){var c=e.routes[b];if(c.regexp.exec(a))return c}return null},a.$on("$routeChangeStart",function(a,c){c.resolve=c.resolve||{},b.onRouteChange(c,function(a){c.resolve._visorDelay=function(){return a}})}))}])}(),function(){b.module("visor.permissions",[]).provider("visorPermissions",[function(){var a=this;a.getPermissionsFromNext=function(a){return a.restrict?[a.restrict]:[]},a.doBeforeFirstCheck=[],a.onNotAllowed=function(){},a.invokeParameters=[],a.getRoute=function(a){throw new Error("method not implemented")};var d=!1;this.$get=["$q","$injector","$location",function(e,f,g){function h(a){if(!a||0===a.length)return!0;b.isArray(a)||(a=[a]);var c=!0;return a.forEach(function(a){c=c&&a.apply(null,l.invokeParameters)}),c}function i(b,c){var d=h(c);return d?!0:(l.invokeNotAllowed(a.onNotAllowed),!1)}var j=[],k={},l={onRouteChange:function(b,c){var g=l.getPermissionsFromNext(b);if(!g||0==g.length)return!0;if(d)return i(b,g);var h=e.defer();return c(h.promise),e.all(a.doBeforeFirstCheck.map(function(a){return f.invoke(a)}))["finally"](function(){d=!0,i(b,g)?h.resolve(!0):h.reject(!1)}),"delayed"},getPermissionsFromNext:a.getPermissionsFromNext,checkPermissionsForRoute:function(a){var b=k[a];if(b!==c)return b;var d=l.getRoute(a);if(!d)return c;var e=l.getPermissionsFromNext(d);return b=h(e),k[a]=b,b},clearPermissionCache:function(){k={},j.forEach(function(a){a&&a()})},notifyOnCacheClear:function(a){return j.push(a),function(){var b=j.indexOf(a);-1!=b&&j.splice(b,1)}},getRoute:a.getRoute,invokeParameters:a.invokeParameters,invokeNotAllowed:function(a){f.invoke(a,null,{restrictedUrl:g.url()})}};return l}]}])}(),function(){b.module("visor.ui-router",["visor.permissions"]).run(["$rootScope","visorPermissions","$injector","$timeout","$location",function(a,b,c,d,e){var f=!1;try{c.get("$state"),f=!0}catch(g){}f&&c.invoke(["$state",function(e){b.getPermissionsFromNext=function(a){for(var b=[];a;)if(a.restrict&&b.unshift(a.restrict),a.parent)a=e.get(a.parent);else if(a.name.indexOf(".")>0){var c=a.name.split(".");c.pop();var d=c.join(".");a=e.get(d)}else a=null;return b};var f=(c.get("$urlRouter"),null),g=!1;a.$on("$stateChangeStart",function(a,c,d){if(g)return void(g=!1);f=e.href(c,d).replace(/^#/,"");var h=b.onRouteChange(c,function(a){a.then(function(){g=!0,e.go(c,d)})});h&&"delayed"!==h||a.preventDefault()}),b.invokeNotAllowed=function(a){d(function(){c.invoke(a,null,{restrictedUrl:f})},0)},b.getRoute=function(a){return e.get(a)}}])}])}()}(window,window.angular);
--------------------------------------------------------------------------------
/sample/lib/angular-cookies.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.4.8
3 | * (c) 2010-2015 Google, Inc. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular, undefined) {'use strict';
7 |
8 | /**
9 | * @ngdoc module
10 | * @name ngCookies
11 | * @description
12 | *
13 | * # ngCookies
14 | *
15 | * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
16 | *
17 | *
18 | *
19 | *
20 | * See {@link ngCookies.$cookies `$cookies`} for usage.
21 | */
22 |
23 |
24 | angular.module('ngCookies', ['ng']).
25 | /**
26 | * @ngdoc provider
27 | * @name $cookiesProvider
28 | * @description
29 | * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
30 | * */
31 | provider('$cookies', [function $CookiesProvider() {
32 | /**
33 | * @ngdoc property
34 | * @name $cookiesProvider#defaults
35 | * @description
36 | *
37 | * Object containing default options to pass when setting cookies.
38 | *
39 | * The object may have following properties:
40 | *
41 | * - **path** - `{string}` - The cookie will be available only for this path and its
42 | * sub-paths. By default, this would be the URL that appears in your base tag.
43 | * - **domain** - `{string}` - The cookie will be available only for this domain and
44 | * its sub-domains. For obvious security reasons the user agent will not accept the
45 | * cookie if the current domain is not a sub domain or equals to the requested domain.
46 | * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
47 | * or a Date object indicating the exact date/time this cookie will expire.
48 | * - **secure** - `{boolean}` - The cookie will be available only in secured connection.
49 | *
50 | * Note: by default the address that appears in your `` tag will be used as path.
51 | * This is important so that cookies will be visible for all routes in case html5mode is enabled
52 | *
53 | **/
54 | var defaults = this.defaults = {};
55 |
56 | function calcOptions(options) {
57 | return options ? angular.extend({}, defaults, options) : defaults;
58 | }
59 |
60 | /**
61 | * @ngdoc service
62 | * @name $cookies
63 | *
64 | * @description
65 | * Provides read/write access to browser's cookies.
66 | *
67 | *
68 | * Up until Angular 1.3, `$cookies` exposed properties that represented the
69 | * current browser cookie values. In version 1.4, this behavior has changed, and
70 | * `$cookies` now provides a standard api of getters, setters etc.
71 | *
72 | *
73 | * Requires the {@link ngCookies `ngCookies`} module to be installed.
74 | *
75 | * @example
76 | *
77 | * ```js
78 | * angular.module('cookiesExample', ['ngCookies'])
79 | * .controller('ExampleController', ['$cookies', function($cookies) {
80 | * // Retrieving a cookie
81 | * var favoriteCookie = $cookies.get('myFavorite');
82 | * // Setting a cookie
83 | * $cookies.put('myFavorite', 'oatmeal');
84 | * }]);
85 | * ```
86 | */
87 | this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
88 | return {
89 | /**
90 | * @ngdoc method
91 | * @name $cookies#get
92 | *
93 | * @description
94 | * Returns the value of given cookie key
95 | *
96 | * @param {string} key Id to use for lookup.
97 | * @returns {string} Raw cookie value.
98 | */
99 | get: function(key) {
100 | return $$cookieReader()[key];
101 | },
102 |
103 | /**
104 | * @ngdoc method
105 | * @name $cookies#getObject
106 | *
107 | * @description
108 | * Returns the deserialized value of given cookie key
109 | *
110 | * @param {string} key Id to use for lookup.
111 | * @returns {Object} Deserialized cookie value.
112 | */
113 | getObject: function(key) {
114 | var value = this.get(key);
115 | return value ? angular.fromJson(value) : value;
116 | },
117 |
118 | /**
119 | * @ngdoc method
120 | * @name $cookies#getAll
121 | *
122 | * @description
123 | * Returns a key value object with all the cookies
124 | *
125 | * @returns {Object} All cookies
126 | */
127 | getAll: function() {
128 | return $$cookieReader();
129 | },
130 |
131 | /**
132 | * @ngdoc method
133 | * @name $cookies#put
134 | *
135 | * @description
136 | * Sets a value for given cookie key
137 | *
138 | * @param {string} key Id for the `value`.
139 | * @param {string} value Raw value to be stored.
140 | * @param {Object=} options Options object.
141 | * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
142 | */
143 | put: function(key, value, options) {
144 | $$cookieWriter(key, value, calcOptions(options));
145 | },
146 |
147 | /**
148 | * @ngdoc method
149 | * @name $cookies#putObject
150 | *
151 | * @description
152 | * Serializes and sets a value for given cookie key
153 | *
154 | * @param {string} key Id for the `value`.
155 | * @param {Object} value Value to be stored.
156 | * @param {Object=} options Options object.
157 | * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
158 | */
159 | putObject: function(key, value, options) {
160 | this.put(key, angular.toJson(value), options);
161 | },
162 |
163 | /**
164 | * @ngdoc method
165 | * @name $cookies#remove
166 | *
167 | * @description
168 | * Remove given cookie
169 | *
170 | * @param {string} key Id of the key-value pair to delete.
171 | * @param {Object=} options Options object.
172 | * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
173 | */
174 | remove: function(key, options) {
175 | $$cookieWriter(key, undefined, calcOptions(options));
176 | }
177 | };
178 | }];
179 | }]);
180 |
181 | angular.module('ngCookies').
182 | /**
183 | * @ngdoc service
184 | * @name $cookieStore
185 | * @deprecated
186 | * @requires $cookies
187 | *
188 | * @description
189 | * Provides a key-value (string-object) storage, that is backed by session cookies.
190 | * Objects put or retrieved from this storage are automatically serialized or
191 | * deserialized by angular's toJson/fromJson.
192 | *
193 | * Requires the {@link ngCookies `ngCookies`} module to be installed.
194 | *
195 | *
196 | * **Note:** The $cookieStore service is **deprecated**.
197 | * Please use the {@link ngCookies.$cookies `$cookies`} service instead.
198 | *
199 | *
200 | * @example
201 | *
202 | * ```js
203 | * angular.module('cookieStoreExample', ['ngCookies'])
204 | * .controller('ExampleController', ['$cookieStore', function($cookieStore) {
205 | * // Put cookie
206 | * $cookieStore.put('myFavorite','oatmeal');
207 | * // Get cookie
208 | * var favoriteCookie = $cookieStore.get('myFavorite');
209 | * // Removing a cookie
210 | * $cookieStore.remove('myFavorite');
211 | * }]);
212 | * ```
213 | */
214 | factory('$cookieStore', ['$cookies', function($cookies) {
215 |
216 | return {
217 | /**
218 | * @ngdoc method
219 | * @name $cookieStore#get
220 | *
221 | * @description
222 | * Returns the value of given cookie key
223 | *
224 | * @param {string} key Id to use for lookup.
225 | * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.
226 | */
227 | get: function(key) {
228 | return $cookies.getObject(key);
229 | },
230 |
231 | /**
232 | * @ngdoc method
233 | * @name $cookieStore#put
234 | *
235 | * @description
236 | * Sets a value for given cookie key
237 | *
238 | * @param {string} key Id for the `value`.
239 | * @param {Object} value Value to be stored.
240 | */
241 | put: function(key, value) {
242 | $cookies.putObject(key, value);
243 | },
244 |
245 | /**
246 | * @ngdoc method
247 | * @name $cookieStore#remove
248 | *
249 | * @description
250 | * Remove given cookie
251 | *
252 | * @param {string} key Id of the key-value pair to delete.
253 | */
254 | remove: function(key) {
255 | $cookies.remove(key);
256 | }
257 | };
258 |
259 | }]);
260 |
261 | /**
262 | * @name $$cookieWriter
263 | * @requires $document
264 | *
265 | * @description
266 | * This is a private service for writing cookies
267 | *
268 | * @param {string} name Cookie name
269 | * @param {string=} value Cookie value (if undefined, cookie will be deleted)
270 | * @param {Object=} options Object with options that need to be stored for the cookie.
271 | */
272 | function $$CookieWriter($document, $log, $browser) {
273 | var cookiePath = $browser.baseHref();
274 | var rawDocument = $document[0];
275 |
276 | function buildCookieString(name, value, options) {
277 | var path, expires;
278 | options = options || {};
279 | expires = options.expires;
280 | path = angular.isDefined(options.path) ? options.path : cookiePath;
281 | if (angular.isUndefined(value)) {
282 | expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
283 | value = '';
284 | }
285 | if (angular.isString(expires)) {
286 | expires = new Date(expires);
287 | }
288 |
289 | var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
290 | str += path ? ';path=' + path : '';
291 | str += options.domain ? ';domain=' + options.domain : '';
292 | str += expires ? ';expires=' + expires.toUTCString() : '';
293 | str += options.secure ? ';secure' : '';
294 |
295 | // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
296 | // - 300 cookies
297 | // - 20 cookies per unique domain
298 | // - 4096 bytes per cookie
299 | var cookieLength = str.length + 1;
300 | if (cookieLength > 4096) {
301 | $log.warn("Cookie '" + name +
302 | "' possibly not set or overflowed because it was too large (" +
303 | cookieLength + " > 4096 bytes)!");
304 | }
305 |
306 | return str;
307 | }
308 |
309 | return function(name, value, options) {
310 | rawDocument.cookie = buildCookieString(name, value, options);
311 | };
312 | }
313 |
314 | $$CookieWriter.$inject = ['$document', '$log', '$browser'];
315 |
316 | angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() {
317 | this.$get = $$CookieWriter;
318 | });
319 |
320 |
321 | })(window, window.angular);
322 |
--------------------------------------------------------------------------------
/sample/lib/angular-route.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.4.8
3 | * (c) 2010-2015 Google, Inc. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular, undefined) {'use strict';
7 |
8 | /**
9 | * @ngdoc module
10 | * @name ngRoute
11 | * @description
12 | *
13 | * # ngRoute
14 | *
15 | * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
16 | *
17 | * ## Example
18 | * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
19 | *
20 | *
21 | *
22 | */
23 | /* global -ngRouteModule */
24 | var ngRouteModule = angular.module('ngRoute', ['ng']).
25 | provider('$route', $RouteProvider),
26 | $routeMinErr = angular.$$minErr('ngRoute');
27 |
28 | /**
29 | * @ngdoc provider
30 | * @name $routeProvider
31 | *
32 | * @description
33 | *
34 | * Used for configuring routes.
35 | *
36 | * ## Example
37 | * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
38 | *
39 | * ## Dependencies
40 | * Requires the {@link ngRoute `ngRoute`} module to be installed.
41 | */
42 | function $RouteProvider() {
43 | function inherit(parent, extra) {
44 | return angular.extend(Object.create(parent), extra);
45 | }
46 |
47 | var routes = {};
48 |
49 | /**
50 | * @ngdoc method
51 | * @name $routeProvider#when
52 | *
53 | * @param {string} path Route path (matched against `$location.path`). If `$location.path`
54 | * contains redundant trailing slash or is missing one, the route will still match and the
55 | * `$location.path` will be updated to add or drop the trailing slash to exactly match the
56 | * route definition.
57 | *
58 | * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
59 | * to the next slash are matched and stored in `$routeParams` under the given `name`
60 | * when the route matches.
61 | * * `path` can contain named groups starting with a colon and ending with a star:
62 | * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
63 | * when the route matches.
64 | * * `path` can contain optional named groups with a question mark: e.g.`:name?`.
65 | *
66 | * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
67 | * `/color/brown/largecode/code/with/slashes/edit` and extract:
68 | *
69 | * * `color: brown`
70 | * * `largecode: code/with/slashes`.
71 | *
72 | *
73 | * @param {Object} route Mapping information to be assigned to `$route.current` on route
74 | * match.
75 | *
76 | * Object properties:
77 | *
78 | * - `controller` – `{(string|function()=}` – Controller fn that should be associated with
79 | * newly created scope or the name of a {@link angular.Module#controller registered
80 | * controller} if passed as a string.
81 | * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller.
82 | * If present, the controller will be published to scope under the `controllerAs` name.
83 | * - `template` – `{string=|function()=}` – html template as a string or a function that
84 | * returns an html template as a string which should be used by {@link
85 | * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
86 | * This property takes precedence over `templateUrl`.
87 | *
88 | * If `template` is a function, it will be called with the following parameters:
89 | *
90 | * - `{Array.