Last active
March 4, 2017 22:08
-
-
Save romelgomez/faf8b533b7010d10a9467f7390cf3d16 to your computer and use it in GitHub Desktop.
Firebase login with Angular 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
angular.module('app',[ | |
'ngRoute', | |
'siteConfig', | |
'angular-loading-bar', | |
'filters', | |
'validators', | |
'firebase', | |
'routes', | |
'cgBusy', | |
'jlareau.pnotify', | |
'publications', | |
'login', | |
'account', | |
'ui.bootstrap', | |
'main', | |
'updateMeta', | |
'accountPublications', | |
'trTrustpass', | |
'ngPasswordStrength', | |
'algoliasearch', | |
'images', | |
'ngMessages', | |
'angular-redactor', | |
'uuid', | |
'ngFileUpload' | |
]) | |
.controller('AppController',[ | |
'$scope', | |
'FireAuth', | |
'$location', | |
'SITE_TITLE', | |
'SITE_URL', | |
'SITE_TWITTER', | |
'SITE_CURRENCY_SYMBOL', | |
'CLOUDINARY_CLOUD_NAME', | |
'CLOUDINARY_SITE_DEFAULT_IMAGES', | |
function( $scope, FireAuth, $location, SITE_TITLE, SITE_URL, SITE_TWITTER, SITE_CURRENCY_SYMBOL, CLOUDINARY_CLOUD_NAME, CLOUDINARY_SITE_DEFAULT_IMAGES){ | |
/** | |
* Make available in the all views | |
*/ | |
$scope.SITE_TITLE = SITE_TITLE; | |
$scope.SITE_URL = SITE_URL; | |
$scope.SITE_CURRENCY_SYMBOL = SITE_CURRENCY_SYMBOL; | |
$scope.SITE_TWITTER = SITE_TWITTER; | |
$scope.CLOUDINARY_CLOUD_NAME = CLOUDINARY_CLOUD_NAME; | |
$scope.CLOUDINARY_SITE_DEFAULT_IMAGES = CLOUDINARY_SITE_DEFAULT_IMAGES; | |
FireAuth.$onAuthStateChanged(function(firebaseUser) { | |
$scope.firebaseUser = firebaseUser; | |
}); | |
$scope.$watch(function(){ | |
return $location.path(); | |
},function(){ | |
$scope.locationPath = $location.path(); | |
}); | |
$scope.logout = function() { FireAuth.$signOut(); }; | |
$scope.sizeOf = function(obj) { | |
if (typeof obj === 'undefined'){ | |
obj = {}; | |
} | |
return Object.keys(obj).length; | |
}; | |
$scope.firstObj = function (obj) { | |
for (var key in obj) if (obj.hasOwnProperty(key)) return key; | |
}; | |
}]) | |
.directive('facebook',['$window', 'FACEBOOK_API_ID', 'FACEBOOK_SDK_VERSION', function ($window, FACEBOOK_API_ID, FACEBOOK_SDK_VERSION) { | |
return { | |
restrict:'E', | |
scope:{ | |
url:'=' | |
}, | |
template:''+ | |
'<div class="fb-like" data-href="{{url}}" data-layout="button_count" data-action="like" data-show-faces="true" data-share="true"></div>', | |
link:function(scope){ | |
$window.fbAsyncInit = function() { | |
FB.init({ | |
appId : FACEBOOK_API_ID, | |
xfbml : true, | |
version : FACEBOOK_SDK_VERSION | |
}); | |
}; | |
(function(d, s, id){ | |
var js, fjs = d.getElementsByTagName(s)[0]; | |
if (d.getElementById(id)) {return;} | |
js = d.createElement(s); js.id = id; | |
js.src = '//connect.facebook.net/en_GB/sdk.js'; | |
fjs.parentNode.insertBefore(js, fjs); | |
}(document, 'script', 'facebook-jssdk')); | |
if (typeof $window.FB !== 'undefined'){ | |
scope.$watch(function(scope){ | |
return scope.url; | |
},function(){ | |
$window.FB.XFBML.parse(); | |
}); | |
} | |
} | |
} | |
}]) | |
.directive('customTwitterShareButton',['$window', '$timeout', function ($window, $timeout) { | |
return { | |
restrict:'E', | |
replace: true, | |
scope:{ | |
text:'=', | |
url:'=' | |
}, | |
template:''+ | |
'<a class="twitter-share-button" href="https://twitter.com/intent/tweet?text={{text}}&via=marketoflondon&url={{url}}">Tweet</a>', | |
link:function(){ | |
$timeout(function () { | |
$window.twttr = (function(d, s, id) { | |
var js, fjs = d.getElementsByTagName(s)[0], | |
t = window.twttr || {}; | |
if (d.getElementById(id)) return t; | |
js = d.createElement(s); | |
js.id = id; | |
js.src = 'https://platform.twitter.com/widgets.js'; | |
fjs.parentNode.insertBefore(js, fjs); | |
t._e = []; | |
t.ready = function(f) { | |
t._e.push(f); | |
}; | |
return t; | |
}(document, 'script', 'twitter-wjs')); | |
if(typeof $window.twttr.widgets !== 'undefined'){ | |
$window.twttr.widgets.load(); | |
} | |
}); | |
} | |
} | |
}]) | |
.directive('inputFocus',[function(){ | |
return { | |
restrict:'A', | |
link : function(scope, element) { | |
element.focus(); | |
} | |
}; | |
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* Site configuration | |
****************************/ | |
angular.module('siteConfig',[]) | |
.constant('SITE_URL', 'http://www.marketoflondon.co.uk') | |
.constant('SITE_TITLE', 'Market of London - Real Estate and Jobs Classified Ads - UK') | |
.constant('SITE_EMAIL', '') | |
.constant('SITE_TWITTER', 'marketoflondon') | |
.constant('SITE_CURRENCY_SYMBOL', '£') | |
.constant('CLOUDINARY_CLOUD_NAME', 'berlin') | |
.constant('CLOUDINARY_URL', 'https://api.cloudinary.com/v1_1/berlin/upload') | |
.constant('CLOUDINARY_UPLOAD_PRESET', '---------') | |
.constant('CLOUDINARY_SITE_DEFAULT_IMAGES', { | |
accountBanner: { | |
jpg : 'https://res.cloudinary.com/berlin/image/upload/c_fill,h_617,q_auto:best,w_2000/v1471962346/iceland_q4qb4e.jpg', | |
webp : 'https://res.cloudinary.com/berlin/image/upload/c_fill,h_617,q_auto:best,w_2000/v1471962346/iceland_q4qb4e.webp' | |
}, | |
accountProfileImage:{ | |
jpg: 'https://res.cloudinary.com/berlin/image/upload/c_scale,w_400/v1471961823/unnamedPerson_diuaor.jpg', | |
webp: 'https://res.cloudinary.com/berlin/image/upload/c_scale,w_400/v1471961823/unnamedPerson_diuaor.webp' | |
}, | |
uploadImagesDirective:{ | |
loading:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/q_auto:low/v1471973179/loading_esicpm.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/q_auto:low/v1471973179/loading_esicpm.webp' | |
}, | |
invalidImage:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/q_auto:low/v1471973179/invalid_image_azvsxw.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/q_auto:low/v1471973179/invalid_image_azvsxw.webp' | |
} | |
}, | |
publicationsListDirective:{ | |
anyTypePublicationsBanner:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/q_auto:best/v1478223368/marketoflondon-banner-principal-4_pel5sw.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/q_auto:best/v1478223368/marketoflondon-banner-principal-4_pel5sw.webp' | |
}, | |
shortcutsBanners: { | |
jobs:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475315516/jobs-banner-marketoflondon-1_d5bz8l.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475315516/jobs-banner-marketoflondon-1_d5bz8l.webp' | |
}, | |
transport:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475316003/transport-banner-marketoflondon-1_g37i8n.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475316003/transport-banner-marketoflondon-1_g37i8n.webp' | |
}, | |
realState:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475315781/realstate-banner-marketoflondon-1_ygyywx.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475315781/realstate-banner-marketoflondon-1_ygyywx.webp' | |
}, | |
services:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/c_scale,h_300,q_auto:eco/v1475316083/services-banner-marketoflondon-1_urhnbp.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_scale,h_300,q_auto:eco/v1475316083/services-banner-marketoflondon-1_urhnbp.webp' | |
}, | |
marketplace:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475316159/markeplace-banner-marketoflondon-1_jnkt15.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:eco,w_300/v1475316159/markeplace-banner-marketoflondon-1_jnkt15.webp' | |
} | |
}, | |
noImageAvailableBig:{ | |
jpg:'https://res.cloudinary.com/berlin/image/upload/c_fill,h_400,q_auto:low,w_700/noImageAvailableBig_lxxmuu.jpg', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_fill,h_400,q_auto:low,w_700/noImageAvailableBig_lxxmuu.webp' | |
}, | |
algoliaLogo:{ | |
png:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:low,w_70/v1472131370/Algolia_logo_bg-white_jn2n2w.png', | |
webp:'https://res.cloudinary.com/berlin/image/upload/c_scale,q_auto:low,w_70/v1472131370/Algolia_logo_bg-white_jn2n2w.webp' | |
} | |
} | |
}) | |
.constant('ALGOLIA_APPLICATION_ID', '---------') | |
.constant('ALGOLIA_API_KEY', '------------------------------------') | |
.constant('FACEBOOK_API_ID', '------------------') | |
.constant('FACEBOOK_SDK_VERSION', 'v2.7') | |
.constant('FIRE_BASE_CONFIG', { | |
apiKey: '---------------------------', | |
authDomain: '<app-name>.firebaseapp.com', | |
databaseURL: 'https://<app-name>.firebaseio.com', | |
storageBucket: 'project-------------------.appspot.com' | |
}) | |
.config(['FIRE_BASE_CONFIG', function (FIRE_BASE_CONFIG) { | |
firebase.initializeApp(FIRE_BASE_CONFIG); | |
}]) | |
.factory('FireAuth', ['$firebaseAuth', function($firebaseAuth) { | |
return $firebaseAuth(); | |
}]) | |
.factory('FireRef', ['$window', function($window) { | |
return $window.firebase.database().ref(); | |
}]) | |
.run(function(){ | |
/** | |
* Google Analytics App ID | |
*/ | |
var googleAppID = 'UA-----------1'; | |
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | |
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | |
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | |
})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); | |
ga('create', googleAppID, 'auto'); | |
ga('send', 'pageview'); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container view-container"> | |
<div class="panel panel-default" cg-busy="{promise:httpRequestPromise,message:'Just a moment'}"> | |
<div class="panel-heading"> | |
<h3 class="panel-title">Login Page</h3> | |
</div> | |
<div class="panel-body"> | |
<uib-tabset> | |
<uib-tab heading="I'm a returning customer"> | |
<div style="margin-top: 10px;"> | |
<!-- Login Form --> | |
<div ng-form="forms.signIn" style="margin-top: 10px;"> | |
<!-- Email input --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.signIn.$submitted && forms.signIn.email.$valid),'has-error has-feedback': (forms.signIn.$submitted && forms.signIn.email.$invalid) }"> | |
<label class="control-label"><i class="fa fa-envelope"></i> Email <sup style="color: red;">*</sup></label> | |
<input type="email" name="email" ng-model="model.signIn.email" required class="form-control" placeholder=""> | |
<span ng-show="forms.signIn.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.signIn.email.$valid),'glyphicon-remove': ( forms.signIn.email.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.signIn.$submitted && forms.signIn.email.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>email</b> is required. | |
</div> | |
<div data-ng-message="email"> | |
- The <b>email</b> must be valid. | |
</div> | |
</div> | |
</div> | |
<!-- Password input --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.signIn.$submitted && forms.signIn.password.$valid),'has-error has-feedback': (forms.signIn.$submitted && forms.signIn.password.$invalid) }"> | |
<label class="control-label"><i class="fa fa-key"></i> Password <sup style="color: red;">*</sup></label> | |
<input type="{{showPassword ? 'text' : 'password'}}" name="password" ng-model="model.signIn.password" required minlength="7" class="form-control" placeholder=""> | |
<span ng-show="forms.signIn.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.signIn.password.$valid),'glyphicon-remove': ( forms.signIn.password.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.signIn.$submitted && forms.signIn.password.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>password</b> is required. | |
</div> | |
<div data-ng-message="minlength" > | |
- The <b>password</b> must be at least 7 characters long. | |
</div> | |
</div> | |
</div> | |
<div style="margin-bottom: 10px;"> | |
<div> | |
<input type="checkbox" ng-model="showPassword"> Show Password? | |
</div> | |
</div> | |
<button class="btn btn-warning" type="button" ng-click="resetSignInForm()"> Reset the form </button> | |
<button class="btn btn-primary" type="submit" ng-click="signIn()"> Sign in </button> | |
</div> | |
<div class="text-center">OR</div> | |
<hr style="margin-top: 0;"> | |
<!-- Social login --> | |
<div> | |
<!-- Redirect Login --> | |
<div class="visible-xs-block visible-sm-block"> | |
<!-- Facebook login --> | |
<!--<a class="btn btn-block btn-social btn-facebook" ng-click="oauthLogin('facebook.com', true)" > | |
<i class="fa fa-facebook" aria-hidden="true"></i> Sign in with Facebook | |
</a>--> | |
<!-- Twitter login --> | |
<a class="btn btn-block btn-social btn-twitter" ng-click="oauthLogin('twitter.com', true)" > | |
<i class="fa fa-twitter" aria-hidden="true"></i> Sign in with Twitter | |
</a> | |
<!-- Google login --> | |
<a class="btn btn-block btn-social btn-google" ng-click="oauthLogin('google.com', true)" > | |
<i class="fa fa-google" aria-hidden="true"></i> Sign in with Google | |
</a> | |
</div> | |
<!-- Pop-up window Login --> | |
<div class="visible-md-block visible-lg-block"> | |
<!-- Facebook login --> | |
<!--<a class="btn btn-block btn-social btn-facebook" ng-click="oauthLogin('facebook.com')" > | |
<i class="fa fa-facebook" aria-hidden="true"></i> Sign in with Facebook | |
</a>--> | |
<!-- Twitter login --> | |
<a class="btn btn-block btn-social btn-twitter" ng-click="oauthLogin('twitter.com')" > | |
<i class="fa fa-twitter" aria-hidden="true"></i> Sign in with Twitter | |
</a> | |
<!-- Google login --> | |
<a class="btn btn-block btn-social btn-google" ng-click="oauthLogin('google.com')" > | |
<i class="fa fa-google" aria-hidden="true"></i> Sign in with Google | |
</a> | |
</div> | |
</div> | |
</div> | |
</uib-tab> | |
<uib-tab heading="Register"> | |
<div style="margin-top: 10px;"> | |
<!-- Register Form --> | |
<div ng-form="forms.register"> | |
<!-- Names input --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.register.$submitted && forms.register.names.$valid),'has-error has-feedback': (forms.register.$submitted && forms.register.names.$invalid) }"> | |
<label class="control-label"> Names <sup class="required">*</sup></label> | |
<input type="text" name="names" ng-model="model.register.names" ng-trim no-special-chars required capitalize class="form-control" placeholder=""> | |
<span ng-show="forms.register.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.register.names.$valid),'glyphicon-remove': ( forms.register.names.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.register.$submitted && forms.register.names.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>names</b> are required. | |
</div> | |
<div data-ng-message="noSpecialChars"> | |
- Not allowed to use special characters. | |
</div> | |
</div> | |
</div> | |
<!-- Last Names input --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.register.$submitted && forms.register.lastNames.$valid),'has-error has-feedback': (forms.register.$submitted && forms.register.lastNames.$invalid) }"> | |
<label class="control-label"> Last Names <sup class="required">*</sup></label> | |
<input type="text" name="lastNames" ng-model="model.register.lastNames" ng-trim no-special-chars required capitalize class="form-control" placeholder=""> | |
<span ng-show="forms.register.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.register.lastNames.$valid),'glyphicon-remove': ( forms.register.lastNames.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.register.$submitted && forms.register.lastNames.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>Last Names</b> are required. | |
</div> | |
<div data-ng-message="noSpecialChars"> | |
- Not allowed to use special characters. | |
</div> | |
</div> | |
</div> | |
<!-- Email input --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.register.$submitted && forms.register.email.$valid),'has-error has-feedback': (forms.register.$submitted && forms.register.email.$invalid) }"> | |
<label class="control-label"><i class="fa fa-envelope"></i> Email <sup class="required">*</sup></label> | |
<input type="email" name="email" ng-model="model.register.email" required class="form-control" placeholder=""> | |
<span ng-show="forms.register.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.register.email.$valid),'glyphicon-remove': ( forms.register.email.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.register.$submitted && forms.register.email.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>email</b> is required. | |
</div> | |
<div data-ng-message="email"> | |
- The <b>email</b> must be valid. | |
</div> | |
</div> | |
</div> | |
<!-- Password input --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.register.$submitted && forms.register.password.$valid),'has-error has-feedback': (forms.register.$submitted && forms.register.password.$invalid) }"> | |
<label class="control-label"><i class="fa fa-key"></i> Password <sup class="required">*</sup></label> | |
<input | |
class="form-control" | |
type="password" | |
name="password" | |
ng-model="model.register.password" | |
required | |
minlength="7" | |
maxlength="50" | |
placeholder="" | |
tr-trustpass="{maximum: true,messageGuide: 'Make sure your password meets these requirements:',messageDone:'¡Excellent! Your password is acceptable.',lowercaseLabel:'One lowercase character.',uppercaseLabel:'One uppercase character.',numberLabel:'One number.',specialLabel:'One special character.',minimumLabel:'Minimum characters:',maximumLabel:'Maximum characters:'}" | |
> | |
<span ng-show="forms.register.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.register.password.$valid),'glyphicon-remove': ( forms.register.password.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.register.$submitted && forms.register.password.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>new password</b> is required. | |
</div> | |
<div data-ng-message="minlength" > | |
- The <b>new password</b> must be at least 7 characters long. | |
</div> | |
<div data-ng-message="trustpass" > | |
- Make sure you meet the minimum requirements described above. | |
</div> | |
</div> | |
<div>Password strength: {{passStrength}}%</div> | |
<div ng-password-strength="model.register.password" strength="passStrength" inner-class="progress-bar" inner-class-prefix="progress-bar-"></div> | |
</div> | |
<!-- Same Password --> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.register.$submitted && forms.register.samePassword.$valid),'has-error has-feedback': (forms.register.$submitted && forms.register.samePassword.$invalid) }"> | |
<label class="control-label"><i class="fa fa-key"></i> Same Password <sup class="required">*</sup></label> | |
<input type="password" name="samePassword" ng-model="model.register.samePassword" required match="model.register.password" minlength="7" class="form-control" placeholder=""> | |
<span ng-show="forms.register.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.register.password.$valid),'glyphicon-remove': ( forms.register.password.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.register.$submitted && forms.register.samePassword.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>same password</b> is required. | |
</div> | |
<div data-ng-message="match"> | |
- The <b>passwords</b> do not match!. | |
</div> | |
<div data-ng-message="minlength" > | |
- The <b>password</b> must be at least 7 characters long. | |
</div> | |
</div> | |
</div> | |
<!-- Reset the form button --> | |
<button class="btn btn-warning" type="button" ng-click="resetRegisterForm()"> Reset the form </button> | |
<!-- Sign in button--> | |
<button class="btn btn-primary" type="submit" ng-click="register()"> Sign in </button> | |
</div> | |
<hr> | |
<div class="alert alert-info alert-xs" role="alert"><sup class="required">*</sup> Is required.</div> | |
</div> | |
</uib-tab> | |
<uib-tab heading="Recover account"> | |
<!-- Recover account form --> | |
<div ng-form="forms.recoverAccount" style="margin-top: 10px;"> | |
<div class="form-group" ng-class="{'has-success has-feedback': (forms.recoverAccount.$submitted && forms.recoverAccount.email.$valid),'has-error has-feedback': (forms.recoverAccount.$submitted && forms.recoverAccount.email.$invalid) }"> | |
<label class="control-label"><i class="fa fa-envelope"></i> Email <sup class="required">*</sup></label> | |
<input type="email" name="email" ng-model="model.recoverAccount.email" required class="form-control" placeholder=""> | |
<span ng-show="forms.recoverAccount.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.recoverAccount.email.$valid),'glyphicon-remove': ( forms.recoverAccount.email.$invalid) }" aria-hidden="true"></span> | |
<div data-ng-messages="forms.recoverAccount.$submitted && forms.recoverAccount.email.$error" class="help-block"> | |
<div data-ng-message="required"> | |
- The <b>email</b> is required. | |
</div> | |
<div data-ng-message="email"> | |
- The <b>email</b> must be valid. | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Recover account submit form button --> | |
<button class="btn btn-primary" type="submit" ng-click="recover()"> Recover </button> | |
</uib-tab> | |
</uib-tabset> | |
</div> | |
</div> | |
</div> | |
<update-title title="{{SITE_TITLE}}"></update-title> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
angular.module('login',[]) | |
.controller('LoginController', [ | |
'$q', | |
'$window', | |
'$scope', | |
'$location', | |
'$uibModal', | |
'FireAuth', | |
'FireRef', | |
'notificationService', | |
function ($q, $window, $scope, $location, $uibModal, FireAuth, FireRef, notificationService) { | |
// watch for login status changes and redirect if appropriate | |
FireAuth.$onAuthStateChanged(function (authenticatedUser) { | |
if( authenticatedUser !== null) { | |
var deferred = $q.defer(); | |
$scope.httpRequestPromise = deferred.promise; | |
var promises = []; | |
var credential; | |
//https://firebase.google.com/docs/auth/web/account-linking#link-auth-provider-credentials-to-a-user-account | |
if(authenticatedUser.email !== null){ | |
var provider = $window.sessionStorage.getItem(authenticatedUser.email+'?provider'); | |
if(provider !== null){ | |
switch (provider) { | |
case 'facebook.com': | |
credential = firebase.auth.FacebookAuthProvider.credential($window.sessionStorage.getItem(authenticatedUser.email+'?accessToken')); | |
break; | |
case 'google.com': | |
console.log('TODO set credential for: google.com'); | |
notificationService.error('TODO set credential for: google.com'); | |
break; | |
case 'twitter.com': | |
credential = firebase.auth.TwitterAuthProvider.credential($window.sessionStorage.getItem(authenticatedUser.email+'?accessToken'), $window.sessionStorage.getItem(authenticatedUser.email+'?secret')); | |
break; | |
} | |
if(typeof credential !== 'undefined' && credential !== null){ | |
promises.push(authenticatedUser.link(credential)); | |
} | |
} | |
} | |
promises.push(createProfile(authenticatedUser)); | |
$q.all(promises) | |
.then(function(){ | |
if(typeof credential !== 'undefined' && credential !== null){ | |
$window.sessionStorage.removeItem(authenticatedUser.email+'?provider'); | |
$window.sessionStorage.removeItem(authenticatedUser.email+'?accessToken'); | |
} | |
deferred.resolve(); | |
$location.path('/new-publication'); | |
}); | |
} | |
}); | |
var original = angular.copy($scope.model = { | |
signIn:{ | |
email:'', | |
password:'', | |
rememberMe: false | |
}, | |
register:{ | |
names:'', | |
lastNames:'', | |
email:'', | |
password:'', | |
samePassword:'' | |
}, | |
recoverAccount:{ | |
email:'' | |
} | |
}); | |
$scope.forms = { | |
signIn: {}, | |
register:{}, | |
recoverAccount:{} | |
}; | |
$scope.resetRegisterForm = function(){ | |
angular.copy(original.register,$scope.model.register); | |
$scope.forms.register.$setUntouched(); | |
$scope.forms.register.$setPristine(); | |
}; | |
$scope.resetSignInForm = function(){ | |
angular.copy(original.signIn,$scope.model.signIn); | |
$scope.forms.signIn.$setUntouched(); | |
$scope.forms.signIn.$setPristine(); | |
}; | |
function resetRecoverAccountForm(){ | |
angular.copy(original.recoverAccount,$scope.model.recoverAccount); | |
$scope.forms.recoverAccount.$setUntouched(); | |
$scope.forms.recoverAccount.$setPristine(); | |
} | |
/** | |
* show error | |
* @param {Object} error | |
**/ | |
function showError(error) { | |
switch (error.code) { | |
case 'auth/invalid-email': | |
notificationService.error('The email is invalid.'); | |
break; | |
case 'auth/user-disabled': | |
notificationService.error('This account has been suspended.'); | |
break; | |
case 'auth/user-not-found': | |
notificationService.error('There is not user for this email.'); | |
break; | |
case 'auth/wrong-password': | |
notificationService.error('The password is invalid'); | |
break; | |
case 'auth/popup-closed-by-user': | |
notificationService.error('The popup has been closed before finalizing the operation.'); | |
break; | |
case 'auth/network-request-failed': | |
notificationService.error('A network error has occurred.'); | |
break; | |
case 'auth/account-exists-with-different-credential': | |
attemptLinkCredential(error.email, error.credential); | |
break; | |
case 'auth/email-already-in-use': | |
notificationService.error('The email address is already in use by another account.'); | |
break; | |
default: | |
notificationService.error('Undefined Error'); | |
} | |
} | |
/** | |
* Create the profile | |
* @param {Object} firebaseUser | |
**/ | |
function createProfile(firebaseUser) { | |
var deferred = $q.defer(); | |
var reference = FireRef.child('users').child(firebaseUser.uid); | |
var profile = {}; | |
reference.once('value', function(snapshot) { | |
var exists = (snapshot.val() !== null); | |
if(!exists){ | |
switch(firebaseUser.providerData[0].providerId) { | |
case 'facebook.com': | |
profile.names = firebaseUser.providerData[0].displayName; | |
profile.provider = firebaseUser.providerData[0].providerId; | |
profile.startedAt = $window.firebase.database.ServerValue.TIMESTAMP; | |
break; | |
case 'twitter.com': | |
profile.names = firebaseUser.providerData[0].displayName; | |
profile.provider = firebaseUser.providerData[0].providerId; | |
profile.startedAt = $window.firebase.database.ServerValue.TIMESTAMP; | |
break; | |
case 'google.com': | |
profile.names = firebaseUser.providerData[0].displayName; | |
profile.provider = firebaseUser.providerData[0].providerId; | |
profile.startedAt = $window.firebase.database.ServerValue.TIMESTAMP; | |
break; | |
case 'password': | |
profile.email = $scope.model.register.email; | |
profile.names = $scope.model.register.names; | |
profile.lastNames = $scope.model.register.lastNames; | |
profile.provider = firebaseUser.providerData[0].providerId; | |
profile.startedAt = $window.firebase.database.ServerValue.TIMESTAMP; | |
break; | |
} | |
reference.set(profile, function(error) { | |
if (error) { | |
deferred.reject(error); | |
} else { | |
deferred.resolve(); | |
} | |
}); | |
}else{ | |
deferred.resolve(); | |
} | |
}); | |
return deferred.promise; | |
} | |
$scope.signIn = function(){ | |
$scope.forms.signIn.$setSubmitted(true); | |
if($scope.forms.signIn.$valid){ | |
$scope.httpRequestPromise = FireAuth.$signInWithEmailAndPassword($scope.model.signIn.email, $scope.model.signIn.password) | |
.then(null, showError); | |
} | |
}; | |
$scope.recover = function(){ | |
$scope.forms.recoverAccount.$setSubmitted(true); | |
if($scope.forms.recoverAccount.$valid){ | |
$scope.httpRequestPromise = FireAuth.$sendPasswordResetEmail($scope.model.recoverAccount.email) | |
.then(function(){ | |
resetRecoverAccountForm(); | |
notificationService.success('Password reset email sent successfully!'); | |
},function(error){ | |
showError(error); | |
}); | |
} | |
}; | |
function promptForLinkCredential (size, email, credential, providers){ | |
var modalInstance = $uibModal.open({ | |
templateUrl: 'static/assets/views/login/modals/promptForLinkCredentialModal.html', | |
controller: 'PromptForLinkCredentialController', | |
size: size, | |
resolve: { | |
credential: function () { | |
return credential; | |
}, | |
providers: function () { | |
return providers; | |
}, | |
email: function () { | |
return email; | |
} | |
} | |
}); | |
modalInstance.result.then(function (result) { | |
$window.sessionStorage.setItem(email+'?provider', result.credential.provider); | |
$window.sessionStorage.setItem(email+'?accessToken', result.credential.accessToken); | |
switch(result.credential.provider) { | |
case 'facebook.com': | |
break; | |
case 'twitter.com': | |
$window.sessionStorage.setItem(email+'?secret', result.credential.secret); | |
break; | |
case 'google.com': | |
$window.sessionStorage.setItem(email+'?idToken', result.credential.idToken); | |
break; | |
} | |
if(result.credential.provider !== 'password'){ | |
$scope.oauthLogin(result.provider, result.redirect); | |
} | |
}); | |
} | |
function attemptLinkCredential (email, credential){ | |
$window.firebase.auth().fetchProvidersForEmail(email).then(function(providers) { | |
promptForLinkCredential('lg', email, credential, providers); | |
}); | |
} | |
$scope.register = function(){ | |
$scope.forms.register.$setSubmitted(true); | |
if($scope.forms.register.$valid){ | |
$scope.httpRequestPromise = FireAuth.$createUserWithEmailAndPassword($scope.model.register.email, $scope.model.register.password) | |
.then(null, showError); | |
} | |
}; | |
/** | |
* Get Redirect Result | |
*/ | |
$window.firebase.auth().getRedirectResult() | |
.then(null,function(error){ | |
console.log('error', error); | |
attemptLinkCredential(error.email, error.credential); | |
}); | |
$scope.oauthLogin = function(provider, signInWithRedirect) { | |
var authProvider; | |
switch(provider) { | |
case 'facebook.com': | |
authProvider = new $window.firebase.auth.FacebookAuthProvider(); | |
authProvider.addScope('email'); | |
break; | |
case 'twitter.com': | |
authProvider = new $window.firebase.auth.TwitterAuthProvider(); | |
break; | |
case 'google.com': | |
authProvider = new firebase.auth.GoogleAuthProvider(); | |
break; | |
} | |
if(typeof signInWithRedirect !== 'undefined' && signInWithRedirect === true){ | |
// returns firebase.Promise containing void | |
$scope.httpRequestPromise = FireAuth.$signInWithRedirect(authProvider) | |
.then(null, showError); | |
}else{ | |
// returns firebase.auth.UserCredential {user: nullable firebase.User, credential: nullable firebase.auth.AuthCredential} | |
$scope.httpRequestPromise = FireAuth.$signInWithPopup(authProvider) | |
.then(null, showError); | |
} | |
}; | |
}]) | |
.controller('PromptForLinkCredentialController',['$scope','$uibModalInstance', '$q', 'providers', 'credential', function($scope, $uibModalInstance, $q, providers, credential){ | |
$scope.providers = providers; | |
$scope.credential = credential; | |
$scope.loginWith = function(provider, redirect){ | |
$uibModalInstance.close({ | |
provider: provider, | |
redirect: typeof redirect !== 'undefined'? redirect : false, | |
credential: credential | |
}); | |
}; | |
$scope.cancel = function () { | |
$uibModalInstance.dismiss(); | |
}; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment