-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathng-navigation-service.js
168 lines (159 loc) · 5.9 KB
/
ng-navigation-service.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* globals define, module */
(function (root, factory) {
'use strict';
if (typeof module !== 'undefined' && module.exports) {
factory(
typeof _ === 'undefined' ? require('lodash') : root._,
typeof angular === 'undefined' ? require('angular') : root.angular
);
module.exports = 'ng-navigation-service';
} else if (typeof define === 'function' && define.amd) {
define(['lodash', 'angular'], factory);
} else {
factory(root._, root.angular);
}
}(this, function (_, angular, undefined) {
'use strict';
angular.module('navigation.service', []).provider('$navigation', function () {
var configuration = {
activeLinkDecorator: undefined,
inactiveLinkDecorator: undefined,
securityService: undefined,
extensions: undefined,
roleToAudienceMapFunction: function (userRole) {
return userRole;
},
inAudienceValidationFunction: function (userRoles, audiences) {
var userAudiences = _.flatten(_.map(userRoles, this.roleToAudienceMapFunction));
return !_.isEmpty(userAudiences) && !_.isEmpty(audiences) &&
_.some(audiences, function (audience) { return _.includes(userAudiences, audience); });
}
};
/**
* call this function to provide configuration options to the service.
*/
this.configure = function (configurationOpts) {
configuration = _.defaults(configurationOpts, configuration);
};
this.$get = ['$injector', '$location', '$log', '$window', function ($injector, $location, $log, $window) {
var secService;
var securityService = function () {
if (_.isUndefined(secService)) {
if (!_.isString(configuration.securityService)) {
$log.error('No securityService configuration value provided');
return undefined;
}
if (!$injector.has(configuration.securityService)) {
$log.error('No matching service registered in Angular: ', configuration.securityService);
return undefined;
}
secService = $injector.get(configuration.securityService);
_.each(['isAuthenticated', 'roles'], function (methodName) {
if (!_.has(secService, methodName)) {
$log.error('Matching securityService is missing method: ', methodName);
return undefined;
}
});
}
return secService;
};
var api = {
/**
* returns true if the user is in any of the specified audiences.
*/
inAudience: function () {
var args = _.flatten(_.toArray(arguments));
var authenticated = securityService().isAuthenticated();
// handle 'all' and 'anonymous' special cases
if (args.length === 1 && _.isString(args[0])) {
if (args[0].toUpperCase() === 'ALL') {
return authenticated;
}
if (args[0].toUpperCase() === 'ANONYMOUS') {
return !authenticated;
}
}
// handle generic case of a list of defined roles
if (args.length === 0 || !authenticated) {
return false;
}
return configuration.inAudienceValidationFunction(securityService().roles(), args);
},
/**
* returns true if the location is the current active location.
*/
isActiveLocation: function (location) {
var i, locations, path;
if (!_.isString(location)) {
return false;
}
locations = this.tokenizePath(location);
if (_.isEmpty(locations)) {
return false;
}
path = this.tokenizePath();
if (locations.length > path.length) {
return false;
}
for (i = 0; i < locations.length; ++i) {
if (locations[i] !== path[i]) {
return false;
}
}
return true;
},
/**
* returns the active decorator if the location is the current active location.
* returns the inactive decorator if the location is not the current active location.
*/
decorateLink: function (item, active, inactive) {
active = active || configuration.activeLinkDecorator;
inactive = inactive || configuration.inactiveLinkDecorator;
return this.isActiveLocation(item) ? active : inactive;
},
/**
* call this function to navigate to a route and optionally push the current location to history.
*/
goto: function (route, noHistory) {
if (!_.isString(route)) {
route = '/';
noHistory = false;
}
var location = $location.path(route);
if (noHistory === true) {
// replace prevents the $location service from pushing the previous page to history
location.replace();
}
},
/**
* call this function to pop and navigate to the previous location from history.
*/
back: function () {
$window.history.back();
},
/**
* call this function to get the configuration options.
*/
getConfiguration: function () {
return configuration;
},
/**
* returns an in-order array of lowercase tokens from a location string.
* returns an empty array if no tokens are in the location string.
* returns an in-order array of lowercase tokens from the current active location, if no location parameter is provided.
*/
tokenizePath: function (location) {
if (_.isUndefined(location) || _.isNull(location)) {
location = $location.path();
}
if (!_.isString(location)) {
return [];
}
return _.words(location.toLowerCase(), /[\w\-]+/g);
}
};
return _.defaults(api, configuration.extensions);
}];
});
return angular;
}));