Skip to content

Commit 80112fc

Browse files
author
maenriquez
committed
- Separated the usage of a validator function to it's own function
- Updated the docs accordingly
1 parent abb9bd4 commit 80112fc

File tree

3 files changed

+88
-41
lines changed

3 files changed

+88
-41
lines changed

.docs/angular-meteor/client/views/api/api.auth.html

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222

2323
$meteor.waitForUser()
2424

25-
$meteor.requireUser([validatorFn])
25+
$meteor.requireUser()
26+
27+
$meteor.requireValidUser(validatorFn)
2628

2729
$meteor.loginWithPassword(user, password)
2830

@@ -119,7 +121,7 @@ <h3><p><code><span class="pln">waitForUser();</span></code></p></h3>
119121
});
120122

121123
<br>
122-
<h3><p><code><span class="pln">requireUser([validatorFn]);</span></code></p></h3>
124+
<h3><p><code><span class="pln">requireUser();</span></code></p></h3>
123125

124126
Resolves the promise successfully if a user is authenticated and rejects otherwise.
125127
<br>
@@ -128,10 +130,6 @@ <h3><p><code><span class="pln">requireUser([validatorFn]);</span></code></p></h3
128130
You can catch the rejected promise and redirect the unauthenticated user to a different page, such as the login page.
129131
<br>
130132
See the <a href="/tutorial/step_08#authenticationwithrouters">“Authentication with Routers”</a> section of our tutorial for more information and a full example.
131-
<br>
132-
This method can receive a function as a parameter, which can be used to do custom validation prior to resolving/rejecting the promise.
133-
<br>
134-
If the validator function is present, the method will only resolve if the function returns true. If it returns a string, it will reject the promise with such string. Otherwise (false, null, undefined) it will reject the promise with the "FORBIDDEN" error string.
135133

136134

137135

@@ -150,34 +148,77 @@ <h3><p><code><span class="pln">requireUser([validatorFn]);</span></code></p></h3
150148
return $meteor.requireUser();
151149
}]
152150
}
153-
})
154-
.state('admin', {
155-
url: '/admin',
156-
templateUrl: 'client/views/admin.ng.html',
157-
controller: 'AdminController'
158-
resolve: {
159-
"currentUser": ["$meteor", function($meteor){
160-
return $meteor.requireUser(function(user) {
161-
return user.username==='admin';
162-
});
163-
}]
151+
});
152+
153+
app.run(["$rootScope", "$state", function($rootScope, $state) {
154+
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
155+
// We can catch the error thrown when the $meteor.requireUser() promise is rejected
156+
// and redirect the user back to the login page
157+
if (error === "AUTH_REQUIRED") {
158+
// It is better to use $state instead of $location. See Issue #283.
159+
$state.go('logIn');
164160
}
165-
})
166-
.state('admin2', {
167-
url: '/admin2',
168-
templateUrl: 'client/views/admin2.ng.html',
169-
controller: 'Admin2Controller'
161+
});
162+
}]);
163+
164+
<br>
165+
<h3><p><code><span class="pln">requireValidUser(validatorFn);</span></code></p></h3>
166+
167+
Resolves the promise successfully if a user is authenticated and the validatorFn returns true; rejects otherwise.
168+
<br>
169+
This is useful in cases where you want to require a route to have an authenticated user and do extra validation like the user's role or group.
170+
<br>
171+
You can catch the rejected promise and redirect the unauthenticated user to a different page, such as the login page.
172+
<br>
173+
See the <a href="/tutorial/step_08#authenticationwithrouters">“Authentication with Routers”</a> section of our tutorial for more information and a full example.
174+
<br>
175+
The mandatory validator function will be called with the authenticated user as the single param and it's expected to return true in order to resolve. If it returns a string, the promise will be rejected using said string as the reason. Any other return (false, null, undefined) will be rejected with the default "FORBIDDEN" reason.
176+
177+
178+
179+
----
180+
181+
#### Example
182+
183+
// In route config ('ui-router' in the example, but works with 'ngRoute' the same way)
184+
$stateProvider
185+
.state('home', {
186+
url: '/',
187+
templateUrl: 'client/views/home.ng.html',
188+
controller: 'HomeController'
170189
resolve: {
171190
"currentUser": ["$meteor", function($meteor){
172-
return $meteor.requireUser(function(user) {
173-
if (user.username==='admin2') {
174-
return true;
175-
}
176-
177-
return 'UNAUTHORIZED';
178-
});
191+
return $meteor.requireUser();
179192
}]
180193
}
194+
})
195+
.state('admin', {
196+
url: '/admin',
197+
templateUrl: 'client/views/admin.ng.html',
198+
controller: 'AdminController'
199+
resolve: {
200+
"currentUser": ["$meteor", function($meteor){
201+
return $meteor.requireUser(function(user) {
202+
return user.username==='admin';
203+
});
204+
}]
205+
}
206+
})
207+
.state('admin2', {
208+
url: '/admin2',
209+
templateUrl: 'client/views/admin2.ng.html',
210+
controller: 'Admin2Controller'
211+
resolve: {
212+
"currentUser": ["$meteor", function($meteor){
213+
return $meteor.requireUser(function(user) {
214+
if (user.username==='admin2') {
215+
return true;
216+
}
217+
218+
return 'UNAUTHORIZED';
219+
});
220+
}]
221+
}
181222
});
182223

183224
app.run(["$rootScope", "$state", function($rootScope, $state) {
@@ -196,7 +237,7 @@ <h3><p><code><span class="pln">requireUser([validatorFn]);</span></code></p></h3
196237
break;
197238
default:
198239
$state.go('internal-client-error');
199-
}
240+
}
200241
});
201242
}]);
202243

angular-meteor.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ angularMeteor.service('$meteor', ['$meteorCollection', '$meteorObject', '$meteor
6868
this.call = $meteorMethods.call;
6969
this.loginWithPassword = $meteorUser.loginWithPassword;
7070
this.requireUser = $meteorUser.requireUser;
71+
this.requireValidUser = $meteorUser.requireValidUser;
7172
this.waitForUser = $meteorUser.waitForUser;
7273
this.createUser = $meteorUser.createUser;
7374
this.changePassword = $meteorUser.changePassword;

modules/angular-meteor-user.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ angularMeteorUser.run(['$rootScope', '$meteorUtils', function($rootScope, $meteo
1212

1313
angularMeteorUser.service('$meteorUser', ['$rootScope', '$meteorUtils', '$q',
1414
function($rootScope, $meteorUtils, $q){
15+
var self = this;
1516

1617
this.waitForUser = function(){
1718

@@ -25,31 +26,35 @@ angularMeteorUser.service('$meteorUser', ['$rootScope', '$meteorUtils', '$q',
2526
return deferred.promise;
2627
};
2728

28-
this.requireUser = function(validatorFn){
29+
this.requireUser = function(){
2930

3031
var deferred = $q.defer();
3132

3233
$meteorUtils.autorun($rootScope, function(){
3334
if ( !Meteor.loggingIn() ) {
3435
if ( Meteor.user() == null)
3536
deferred.reject("AUTH_REQUIRED");
36-
else if (validatorFn) {
37-
var valid = validatorFn( Meteor.user() );
38-
39-
if ( valid === true )
40-
deferred.resolve( Meteor.user() );
41-
else if ( typeof valid === "string" )
42-
deferred.reject( valid );
43-
else
44-
deferred.reject( "FORBIDDEN" );
45-
} else
37+
else
4638
deferred.resolve( Meteor.user() );
4739
}
4840
});
4941

5042
return deferred.promise;
5143
};
5244

45+
this.requireValidUser = function(validatorFn) {
46+
return self.requireUser().then(function(user){
47+
var valid = validatorFn( user );
48+
49+
if ( valid === true )
50+
return user;
51+
else if ( typeof valid === "string" )
52+
return $.reject( valid );
53+
else
54+
return $q.reject( "FORBIDDEN" );
55+
});
56+
};
57+
5358
this.loginWithPassword = function(user, password){
5459

5560
var deferred = $q.defer();

0 commit comments

Comments
 (0)