UNPKG

angularx-social-login

Version:

Social login and authentication module for Angular 4 / 5. Supports authentication with Google and Facebook. Can be extended to other providers also.

649 lines (641 loc) 20.2 kB
import { Injectable, NgModule } from '@angular/core'; import { ReplaySubject, BehaviorSubject } from 'rxjs'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class AuthServiceConfig { /** * @param {?} providers */ constructor(providers) { this.lazyLoad = false; this.providers = new Map(); for (let i = 0; i < providers.length; i++) { /** @type {?} */ let element = providers[i]; this.providers.set(element.id, element.provider); this.lazyLoad = this.lazyLoad || element.lazyLoad; } } } class AuthService { /** * @param {?} config */ constructor(config) { this._user = null; this._authState = new ReplaySubject(1); this._readyState = new BehaviorSubject([]); this.initialized = false; this.providers = config.providers; if (!config.lazyLoad) { this.initialize(); } } /** * @return {?} */ get authState() { return this._authState.asObservable(); } /** * Provides an array of provider ID's as they become ready * @return {?} */ get readyState() { return this._readyState.asObservable(); } /** * @private * @return {?} */ initialize() { this.initialized = true; this.providers.forEach((/** * @param {?} provider * @param {?} key * @return {?} */ (provider, key) => { provider.initialize().then((/** * @return {?} */ () => { /** @type {?} */ let readyProviders = this._readyState.getValue(); readyProviders.push(key); this._readyState.next(readyProviders); provider.getLoginStatus().then((/** * @param {?} user * @return {?} */ (user) => { user.provider = key; this._user = user; this._authState.next(user); })).catch((/** * @param {?} err * @return {?} */ (err) => { this._authState.next(null); })); })); })); } /** * @param {?} providerId * @param {?=} opt * @return {?} */ signIn(providerId, opt) { if (!this.initialized) { this.initialize(); } return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ let providerObject = this.providers.get(providerId); if (providerObject) { providerObject.signIn(opt).then((/** * @param {?} user * @return {?} */ (user) => { user.provider = providerId; resolve(user); this._user = user; this._authState.next(user); })).catch((/** * @param {?} err * @return {?} */ err => { reject(err); })); } else { reject(AuthService.ERR_LOGIN_PROVIDER_NOT_FOUND); } })); } /** * @param {?=} revoke * @return {?} */ signOut(revoke = false) { if (!this.initialized) { this.initialize(); } return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { if (!this._user) { reject(AuthService.ERR_NOT_LOGGED_IN); } else { /** @type {?} */ let providerId = this._user.provider; /** @type {?} */ let providerObject = this.providers.get(providerId); if (providerObject) { providerObject.signOut(revoke).then((/** * @return {?} */ () => { resolve(); this._user = null; this._authState.next(null); })).catch((/** * @param {?} err * @return {?} */ (err) => { reject(err); })); } else { reject(AuthService.ERR_LOGIN_PROVIDER_NOT_FOUND); } } })); } } AuthService.ERR_LOGIN_PROVIDER_NOT_FOUND = 'Login provider not found'; AuthService.ERR_NOT_LOGGED_IN = 'Not logged in'; AuthService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ AuthService.ctorParameters = () => [ { type: AuthServiceConfig } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class SocialLoginModule { /** * @param {?} config * @return {?} */ static initialize(config) { return { ngModule: SocialLoginModule, providers: [ AuthService, { provide: AuthServiceConfig, useValue: config } ] }; } } SocialLoginModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule ], providers: [ AuthService ] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class SocialUser { } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @abstract */ class BaseLoginProvider { constructor() { this._readyState = new BehaviorSubject(false); } /** * @protected * @return {?} */ onReady() { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this._readyState.subscribe((/** * @param {?} isReady * @return {?} */ (isReady) => { if (isReady) { resolve(); } })); })); } /** * @param {?} id * @param {?} src * @param {?} onload * @param {?=} async * @param {?=} inner_text_content * @return {?} */ loadScript(id, src, onload, async = true, inner_text_content = '') { // get document if platform is only browser if (typeof document !== 'undefined' && !document.getElementById(id)) { /** @type {?} */ let signInJS = document.createElement('script'); signInJS.async = async; signInJS.src = src; signInJS.onload = onload; /* if (inner_text_content) // LinkedIn signInJS.text = inner_text_content; */ document.head.appendChild(signInJS); } } } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class GoogleLoginProvider extends BaseLoginProvider { /** * @param {?} clientId * @param {?=} opt */ constructor(clientId, opt = { scope: 'email' }) { super(); this.clientId = clientId; this.opt = opt; } /** * @return {?} */ initialize() { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.loadScript(GoogleLoginProvider.PROVIDER_ID, 'https://apis.google.com/js/platform.js', (/** * @return {?} */ () => { gapi.load('auth2', (/** * @return {?} */ () => { this.auth2 = gapi.auth2.init(Object.assign({}, this.opt, { client_id: this.clientId })); this.auth2.then((/** * @return {?} */ () => { this._readyState.next(true); resolve(); })).catch((/** * @param {?} err * @return {?} */ (err) => { reject(err); })); })); })); })); } /** * @return {?} */ getLoginStatus() { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.onReady().then((/** * @return {?} */ () => { if (this.auth2.isSignedIn.get()) { /** @type {?} */ let user = new SocialUser(); /** @type {?} */ let profile = this.auth2.currentUser.get().getBasicProfile(); /** @type {?} */ let token = this.auth2.currentUser.get().getAuthResponse(true).access_token; /** @type {?} */ let backendToken = this.auth2.currentUser.get().getAuthResponse(true).id_token; user.id = profile.getId(); user.name = profile.getName(); user.email = profile.getEmail(); user.photoUrl = profile.getImageUrl(); user.firstName = profile.getGivenName(); user.lastName = profile.getFamilyName(); user.authToken = token; user.idToken = backendToken; resolve(user); } else { reject('No user is currently logged in.'); } })); })); } /** * @param {?=} opt * @return {?} */ signIn(opt) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.onReady().then((/** * @return {?} */ () => { /** @type {?} */ const offlineAccess = (opt && opt.offline_access) || (this.opt && this.opt.offline_access); /** @type {?} */ let promise = !offlineAccess ? this.auth2.signIn(opt) : this.auth2.grantOfflineAccess(opt); promise.then((/** * @param {?} response * @return {?} */ (response) => { /** @type {?} */ let user = new SocialUser(); /** @type {?} */ let profile = this.auth2.currentUser.get().getBasicProfile(); /** @type {?} */ let token = this.auth2.currentUser.get().getAuthResponse(true).access_token; /** @type {?} */ let backendToken = this.auth2.currentUser.get().getAuthResponse(true).id_token; user.id = profile.getId(); user.name = profile.getName(); user.email = profile.getEmail(); user.photoUrl = profile.getImageUrl(); user.firstName = profile.getGivenName(); user.lastName = profile.getFamilyName(); user.authToken = token; user.idToken = backendToken; if (response && response.code) { user.authorizationCode = response.code; } resolve(user); }), (/** * @param {?} closed * @return {?} */ (closed) => { reject('User cancelled login or did not fully authorize.'); })).catch((/** * @param {?} err * @return {?} */ (err) => { reject(err); })); })); })); } /** * @param {?=} revoke * @return {?} */ signOut(revoke) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.onReady().then((/** * @return {?} */ () => { /** @type {?} */ let signOutPromise; if (revoke) { signOutPromise = this.auth2.disconnect(); } else { signOutPromise = this.auth2.signOut(); } signOutPromise.then((/** * @param {?} err * @return {?} */ (err) => { if (err) { reject(err); } else { resolve(); } })).catch((/** * @param {?} err * @return {?} */ (err) => { reject(err); })); })); })); } } GoogleLoginProvider.PROVIDER_ID = 'GOOGLE'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class FacebookLoginProvider extends BaseLoginProvider { /** * @param {?} clientId * @param {?=} opt * @param {?=} locale * @param {?=} fields * @param {?=} version */ constructor(clientId, opt = { scope: 'email,public_profile' }, locale = 'en_US', fields = 'name,email,picture,first_name,last_name', version = 'v4.0') { super(); this.clientId = clientId; this.opt = opt; this.locale = locale; this.fields = fields; this.version = version; } /** * @return {?} */ initialize() { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.loadScript(FacebookLoginProvider.PROVIDER_ID, `//connect.facebook.net/${this.locale}/sdk.js`, (/** * @return {?} */ () => { FB.init({ appId: this.clientId, autoLogAppEvents: true, cookie: true, xfbml: true, version: this.version }); // FB.AppEvents.logPageView(); #FIX for #18 this._readyState.next(true); resolve(); })); })); } /** * @return {?} */ getLoginStatus() { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.onReady().then((/** * @return {?} */ () => { FB.getLoginStatus((/** * @param {?} response * @return {?} */ (response) => { if (response.status === 'connected') { /** @type {?} */ let authResponse = response.authResponse; FB.api(`/me?fields=${this.fields}`, (/** * @param {?} fbUser * @return {?} */ (fbUser) => { /** @type {?} */ let user = new SocialUser(); user.id = fbUser.id; user.name = fbUser.name; user.email = fbUser.email; user.photoUrl = 'https://graph.facebook.com/' + fbUser.id + '/picture?type=normal'; user.firstName = fbUser.first_name; user.lastName = fbUser.last_name; user.authToken = authResponse.accessToken; user.facebook = fbUser; resolve(user); })); } else { reject('No user is currently logged in.'); } })); })); })); } /** * @param {?=} opt * @return {?} */ signIn(opt) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.onReady().then((/** * @return {?} */ () => { FB.login((/** * @param {?} response * @return {?} */ (response) => { if (response.authResponse) { /** @type {?} */ let authResponse = response.authResponse; FB.api(`/me?fields=${this.fields}`, (/** * @param {?} fbUser * @return {?} */ (fbUser) => { /** @type {?} */ let user = new SocialUser(); user.id = fbUser.id; user.name = fbUser.name; user.email = fbUser.email; user.photoUrl = 'https://graph.facebook.com/' + fbUser.id + '/picture?type=normal'; user.firstName = fbUser.first_name; user.lastName = fbUser.last_name; user.authToken = authResponse.accessToken; user.facebook = fbUser; resolve(user); })); } else { reject('User cancelled login or did not fully authorize.'); } }), this.opt); })); })); } /** * @return {?} */ signOut() { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this.onReady().then((/** * @return {?} */ () => { FB.logout((/** * @param {?} response * @return {?} */ (response) => { resolve(); })); })); })); } } FacebookLoginProvider.PROVIDER_ID = 'FACEBOOK'; export { AuthService, AuthServiceConfig, FacebookLoginProvider, GoogleLoginProvider, SocialLoginModule, SocialUser, BaseLoginProvider as ɵa }; //# sourceMappingURL=angularx-social-login.js.map