|
671 | 671 | this._q = $q; |
672 | 672 | this._timeout = $t; |
673 | 673 | this._rootScope = $rs; |
674 | | - this._deferred = null; |
675 | | - this._authenticated = false; |
| 674 | + this._loginDeferred = null; |
| 675 | + this._getCurrentUserDeferred = []; |
| 676 | + this._currentUserData = undefined; |
676 | 677 |
|
677 | 678 | if (typeof ref == "string") { |
678 | 679 | throw new Error("Please provide a Firebase reference instead " + |
|
688 | 689 | $login: this.login.bind(this), |
689 | 690 | $logout: this.logout.bind(this), |
690 | 691 | $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) |
692 | 695 | }; |
693 | 696 | this._object = object; |
694 | 697 |
|
|
711 | 714 | // method returns a promise, which will be resolved when the login succeeds |
712 | 715 | // (and rejected when an error occurs). |
713 | 716 | 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; |
717 | 728 | }, |
718 | 729 |
|
719 | 730 | // Unauthenticate the Firebase reference. |
720 | 731 | logout: function() { |
| 732 | + //tell the simple login client to log us out. |
721 | 733 | this._authClient.logout(); |
| 734 | + |
| 735 | + //forget who we were, so that any getCurrentUser calls will wait for another user event. |
| 736 | + delete this._currentUserData; |
722 | 737 | }, |
723 | 738 |
|
724 | 739 | // Creates a user for Firebase Simple Login. |
725 | 740 | // Function 'cb' receives an error as the first argument and a |
726 | 741 | // Simple Login user object as the second argument. Pass noLogin=true |
727 | 742 | // 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) { |
729 | 744 | var self = this; |
| 745 | + var deferred = this._q.defer(); |
| 746 | + |
730 | 747 | 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})); |
734 | 755 | } else { |
735 | | - if (!noLogin) { |
736 | | - self.login("password", {email: email, password: password}); |
737 | | - } |
| 756 | + deferred.resolve(user); |
738 | 757 | } |
739 | | - } catch(e) { |
740 | | - self._rootScope.$broadcast("$firebaseSimpleLogin:error", e); |
741 | | - } |
742 | | - if (cb) { |
743 | | - self._timeout(function() { |
744 | | - cb(err, user); |
745 | | - }); |
746 | 758 | } |
747 | 759 | }); |
| 760 | + |
| 761 | + return deferred.promise; |
748 | 762 | }, |
749 | 763 |
|
750 | 764 | // Changes the password for a Firebase Simple Login user. |
751 | 765 | // 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) { |
755 | 768 | 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) { |
757 | 772 | if (err) { |
758 | 773 | self._rootScope.$broadcast("$firebaseSimpleLogin:error", err); |
| 774 | + deferred.reject(err); |
| 775 | + } else { |
| 776 | + deferred.resolve(); |
759 | 777 | } |
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(); |
764 | 808 | } |
765 | 809 | }); |
| 810 | + |
| 811 | + return deferred.promise; |
766 | 812 | }, |
767 | 813 |
|
| 814 | + //Send a password reset email to the user for an email + password account. |
| 815 | + //resetPassword: function() { |
| 816 | + //coming soon... |
| 817 | + //}, |
| 818 | + |
768 | 819 | // Internal callback for any Simple Login event. |
769 | 820 | _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 | + |
770 | 829 | var self = this; |
771 | 830 | 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; |
775 | 834 | } |
776 | 835 | self._rootScope.$broadcast("$firebaseSimpleLogin:error", err); |
777 | | - } else if (user) { |
| 836 | + } else { |
| 837 | + this._currentUserData = user; |
| 838 | + |
778 | 839 | self._timeout(function() { |
779 | 840 | 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); |
785 | 853 | } |
786 | | - }); |
787 | | - } else { |
788 | | - self._timeout(function() { |
789 | | - self._object.user = null; |
790 | | - self._authenticated = false; |
791 | | - self._rootScope.$broadcast("$firebaseSimpleLogin:logout"); |
792 | 854 | }); |
793 | 855 | } |
794 | 856 | } |
795 | 857 | }; |
796 | | - |
797 | 858 | })(); |
0 commit comments