Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit ef0cf84

Browse files
committed
Merge pull request #214 from firebase/andrewedits
Andrewedits
2 parents 96b28d1 + 16db500 commit ef0cf84

File tree

11 files changed

+506
-63
lines changed

11 files changed

+506
-63
lines changed

Gruntfile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ module.exports = function(grunt) {
6464
},
6565
karma: {
6666
unit: {
67-
configFile: 'tests/karma.conf.js'
67+
configFile: 'tests/automatic_karma.conf.js'
6868
},
6969
continuous: {
70-
configFile: 'tests/karma.conf.js',
70+
configFile: 'tests/automatic_karma.conf.js',
7171
singleRun: true,
7272
browsers: ['PhantomJS']
7373
}

angularfire.js

Lines changed: 105 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,9 @@
671671
this._q = $q;
672672
this._timeout = $t;
673673
this._rootScope = $rs;
674-
this._deferred = null;
675-
this._authenticated = false;
674+
this._loginDeferred = null;
675+
this._getCurrentUserDeferred = [];
676+
this._currentUserData = undefined;
676677

677678
if (typeof ref == "string") {
678679
throw new Error("Please provide a Firebase reference instead " +
@@ -688,7 +689,9 @@
688689
$login: this.login.bind(this),
689690
$logout: this.logout.bind(this),
690691
$createUser: this.createUser.bind(this),
691-
$changePassword: this.changePassword.bind(this)
692+
$changePassword: this.changePassword.bind(this),
693+
$removeUser: this.removeUser.bind(this),
694+
$getCurrentUser: this.getCurrentUser.bind(this)
692695
};
693696
this._object = object;
694697

@@ -711,87 +714,145 @@
711714
// method returns a promise, which will be resolved when the login succeeds
712715
// (and rejected when an error occurs).
713716
login: function(provider, options) {
714-
this._deferred = this._q.defer();
715-
this._authClient.login(provider, options);
716-
return this._deferred.promise;
717+
var deferred = this._q.defer();
718+
var self = this;
719+
720+
//To avoid the promise from being fulfilled by our initial login state, make sure we have it before
721+
//triggering the login and creating a new promise.
722+
this.getCurrentUser().then(function() {
723+
self._loginDeferred = deferred;
724+
self._authClient.login(provider, options);
725+
});
726+
727+
return deferred.promise;
717728
},
718729

719730
// Unauthenticate the Firebase reference.
720731
logout: function() {
732+
//tell the simple login client to log us out.
721733
this._authClient.logout();
734+
735+
//forget who we were, so that any getCurrentUser calls will wait for another user event.
736+
delete this._currentUserData;
722737
},
723738

724739
// Creates a user for Firebase Simple Login.
725740
// Function 'cb' receives an error as the first argument and a
726741
// Simple Login user object as the second argument. Pass noLogin=true
727742
// if you don't want the newly created user to also be logged in.
728-
createUser: function(email, password, cb, noLogin) {
743+
createUser: function(email, password, noLogin) {
729744
var self = this;
745+
var deferred = this._q.defer();
746+
730747
self._authClient.createUser(email, password, function(err, user) {
731-
try {
732-
if (err) {
733-
self._rootScope.$broadcast("$firebaseSimpleLogin:error", err);
748+
if (err) {
749+
self._rootScope.$broadcast("$firebaseSimpleLogin:error", err);
750+
deferred.reject(err);
751+
} else {
752+
if (!noLogin) {
753+
//resolve the promise with a new promise for login
754+
deferred.resolve(self.login("password", {email: email, password: password}));
734755
} else {
735-
if (!noLogin) {
736-
self.login("password", {email: email, password: password});
737-
}
756+
deferred.resolve(user);
738757
}
739-
} catch(e) {
740-
self._rootScope.$broadcast("$firebaseSimpleLogin:error", e);
741-
}
742-
if (cb) {
743-
self._timeout(function() {
744-
cb(err, user);
745-
});
746758
}
747759
});
760+
761+
return deferred.promise;
748762
},
749763

750764
// Changes the password for a Firebase Simple Login user.
751765
// Take an email, old password and new password as three mandatory
752-
// arguments. An optional callback may be specified to be notified when the
753-
// password has been changed successfully.
754-
changePassword: function(email, old, np, cb) {
766+
// arguments. Returns a promise.
767+
changePassword: function(email, oldPassword, newPassword) {
755768
var self = this;
756-
self._authClient.changePassword(email, old, np, function(err, user) {
769+
var deferred = this._q.defer();
770+
771+
self._authClient.changePassword(email, oldPassword, newPassword, function(err) {
757772
if (err) {
758773
self._rootScope.$broadcast("$firebaseSimpleLogin:error", err);
774+
deferred.reject(err);
775+
} else {
776+
deferred.resolve();
759777
}
760-
if (cb) {
761-
self._timeout(function() {
762-
cb(err, user);
763-
});
778+
});
779+
780+
return deferred.promise;
781+
},
782+
783+
//Gets a promise for the current user info
784+
getCurrentUser: function() {
785+
var self = this;
786+
var deferred = this._q.defer();
787+
788+
if(self._currentUserData !== undefined) {
789+
deferred.resolve(self._currentUserData);
790+
} else {
791+
self._getCurrentUserDeferred.push(deferred);
792+
}
793+
794+
return deferred.promise;
795+
},
796+
797+
//Remove a user for the listed email address. Returns a promise.
798+
removeUser: function(email, password) {
799+
var self = this;
800+
var deferred = this._q.defer();
801+
802+
self._authClient.removeUser(email, password, function(err) {
803+
if (err) {
804+
self._rootScope.$broadcast("$firebaseSimpleLogin:error", err);
805+
deferred.reject(err);
806+
} else {
807+
deferred.resolve();
764808
}
765809
});
810+
811+
return deferred.promise;
766812
},
767813

814+
//Send a password reset email to the user for an email + password account.
815+
//resetPassword: function() {
816+
//coming soon...
817+
//},
818+
768819
// Internal callback for any Simple Login event.
769820
_onLoginEvent: function(err, user) {
821+
822+
// HACK -- calls to logout() trigger events even if we're not logged in,
823+
// making us get extra events. Throw them away. This should be fixed by
824+
// changing Simple Login so that its callbacks refer directly to the action that caused them.
825+
if(this._currentUserData === user && err === null) {
826+
return;
827+
}
828+
770829
var self = this;
771830
if (err) {
772-
if (self._deferred) {
773-
self._deferred.reject(err);
774-
self._deferred = null;
831+
if (self._loginDeferred) {
832+
self._loginDeferred.reject(err);
833+
self._loginDeferred = null;
775834
}
776835
self._rootScope.$broadcast("$firebaseSimpleLogin:error", err);
777-
} else if (user) {
836+
} else {
837+
this._currentUserData = user;
838+
778839
self._timeout(function() {
779840
self._object.user = user;
780-
self._authenticated = true;
781-
self._rootScope.$broadcast("$firebaseSimpleLogin:login", user);
782-
if (self._deferred) {
783-
self._deferred.resolve(user);
784-
self._deferred = null;
841+
if(user) {
842+
self._rootScope.$broadcast("$firebaseSimpleLogin:login", user);
843+
} else {
844+
self._rootScope.$broadcast("$firebaseSimpleLogin:logout");
845+
}
846+
if (self._loginDeferred) {
847+
self._loginDeferred.resolve(user);
848+
self._loginDeferred = null;
849+
}
850+
while (self._getCurrentUserDeferred.length > 0) {
851+
var def = self._getCurrentUserDeferred.pop();
852+
def.resolve(user);
785853
}
786-
});
787-
} else {
788-
self._timeout(function() {
789-
self._object.user = null;
790-
self._authenticated = false;
791-
self._rootScope.$broadcast("$firebaseSimpleLogin:logout");
792854
});
793855
}
794856
}
795857
};
796-
797858
})();

0 commit comments

Comments
 (0)