ng7-auth
Version:
Firestore Authentication with Angular. A Fork form Anthony Nahas.
1,303 lines (1,242 loc) • 64.5 kB
JavaScript
import { Injectable, EventEmitter, Inject, Component, Input, Output, PLATFORM_ID, NgModule, InjectionToken } from '@angular/core';
import { AngularFirestore, AngularFirestoreModule } from '@angular/fire/firestore';
import { MatSnackBar, MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatIconRegistry, MatButtonModule, MatCardModule, MatChipsModule, MatDialogModule, MatDividerModule, MatIconModule, MatInputModule, MatSnackBarModule, MatTabsModule, MatTooltipModule, MatProgressSpinnerModule, MatProgressBarModule, MatCheckboxModule } from '@angular/material';
import { AngularFireAuth, AngularFireAuthModule } from '@angular/fire/auth';
import { auth } from 'firebase/app';
import 'firebase/auth';
import { FormControl, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { isPlatformBrowser, CommonModule } from '@angular/common';
import { DomSanitizer } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { FirebaseOptionsToken, FirebaseNameOrConfigToken } from '@angular/fire';
import { FlexLayoutModule } from '@angular/flex-layout';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @type {?} */
const collections = {
users: 'users',
};
class FirestoreSyncService {
/**
* @param {?} afs
*/
constructor(afs) {
this.afs = afs;
// this.afs.firestore.settings({timestampsInSnapshots: true});
}
// get timestamp() {
// return firebase.firestore.FieldValue.serverTimestamp();
// }
/**
* @param {?} uid
* @return {?}
*/
getUserDocRefByUID(uid) {
return this.afs.doc(`${collections.users}/${uid}`);
}
/**
* @param {?=} queryFn
* @return {?}
*/
getUsersCollectionRef(queryFn) {
return this.afs.collection(`${collections.users}/`, queryFn);
}
/**
* @param {?} uid
* @return {?}
*/
deleteUserData(uid) {
/** @type {?} */
const userRef = this.getUserDocRefByUID(uid);
return userRef.delete();
}
/**
* @param {?} user
* @return {?}
*/
updateUserData(user) {
// Sets user$ data to firestore on login
/** @type {?} */
const userRef = this.getUserDocRefByUID(user.uid);
/** @type {?} */
const data = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
phoneNumber: user.phoneNumber,
providerId: user.providerId
};
return userRef.set(data, { merge: true });
}
}
FirestoreSyncService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
FirestoreSyncService.ctorParameters = () => [
{ type: AngularFirestore }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @enum {string} */
const Accounts = {
NONE: 'account',
CHECK: 'account-check',
EDIT: 'account-edit',
OFF: 'account-off',
REMOVE: 'account-remove',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/** @type {?} */
const facebookAuthProvider = new auth.FacebookAuthProvider();
/** @type {?} */
const googleAuthProvider = new auth.GoogleAuthProvider();
/** @type {?} */
const twitterAuthProvider = new auth.TwitterAuthProvider();
/** @type {?} */
const githubAuthProvider = new auth.GithubAuthProvider();
/** @enum {string} */
const AuthProvider$$1 = {
ALL: 'all',
ANONYMOUS: 'anonymous',
EmailAndPassword: 'firebase',
Google: 'google',
Facebook: 'facebook',
Twitter: 'twitter',
Github: 'github',
PhoneNumber: 'phoneNumber',
};
class AuthProcessService$$1 {
/**
* @param {?} config
* @param {?} afa
* @param {?} _snackBar
* @param {?} _fireStoreService
*/
constructor(config, afa, _snackBar, _fireStoreService) {
this.config = config;
this.afa = afa;
this._snackBar = _snackBar;
this._fireStoreService = _fireStoreService;
this.onSuccessEmitter = new EventEmitter();
this.onErrorEmitter = new EventEmitter();
}
/**
* Reset the password of the user via email
*
* @param {?} email - the email to reset
* @return {?}
*/
resetPassword(email) {
return this.afa.auth.sendPasswordResetEmail(email)
.then(() => console.log('email sent'))
.catch((error) => this.onErrorEmitter.next(error));
}
/**
* General sign in mechanism to authenticate the users with a firebase project
* using a traditional way, via username and password or by using an authentication provider
* like google, facebook, twitter and github
*
* @param {?} provider - the provider to authenticate with (google, facebook, twitter, github)
* @param {?=} email - (optional) the email of user - used only for a traditional sign in
* @param {?=} password - (optional) the password of user - used only for a traditional sign in
* @return {?}
*/
signInWith(provider, email, password) {
return __awaiter(this, void 0, void 0, function* () {
try {
this.isLoading = true;
/** @type {?} */
let signInResult;
switch (provider) {
case AuthProvider$$1.ANONYMOUS:
signInResult = (/** @type {?} */ (yield this.afa.auth.signInAnonymously()));
break;
case AuthProvider$$1.EmailAndPassword:
signInResult = (/** @type {?} */ (yield this.afa.auth.signInWithEmailAndPassword(email, password)));
break;
case AuthProvider$$1.Google:
signInResult = (/** @type {?} */ (yield this.afa.auth.signInWithPopup(googleAuthProvider)));
break;
case AuthProvider$$1.Facebook:
signInResult = (/** @type {?} */ (yield this.afa.auth.signInWithPopup(facebookAuthProvider)));
break;
case AuthProvider$$1.Twitter:
signInResult = (/** @type {?} */ (yield this.afa.auth.signInWithPopup(twitterAuthProvider)));
break;
case AuthProvider$$1.Github:
signInResult = (/** @type {?} */ (yield this.afa.auth.signInWithPopup(githubAuthProvider)));
break;
default:
throw new Error(`${AuthProvider$$1[provider]} is not available as auth provider`);
}
yield this.handleSuccess(signInResult);
}
catch (err) {
this.handleError(err);
console.error(err);
// this._snackBar.open(err.message, 'OK', {duration: 5000});
this.onErrorEmitter.next(err);
}
finally {
this.isLoading = false;
}
});
}
/**
* Sign up new users via email and password.
* After that the user should verify and confirm an email sent via the firebase
*
* @param {?} name - the name if the new user
* @param {?} email - the email if the new user
* @param {?} password - the password if the new user
* @return {?}
*/
signUp(name, email, password) {
return __awaiter(this, void 0, void 0, function* () {
try {
this.isLoading = true;
/** @type {?} */
const userCredential = yield this.afa.auth.createUserWithEmailAndPassword(email, password);
/** @type {?} */
const user = userCredential.user;
console.log('onsignUp the user = ', user);
yield this._fireStoreService
.getUserDocRefByUID(user.uid)
.set((/** @type {?} */ ({
uid: user.uid,
displayName: name,
email: user.email,
photoURL: user.photoURL
})));
yield user.sendEmailVerification();
yield this.updateProfile(name, user.photoURL);
this.emailConfirmationSent = true;
this.emailToConfirm = email;
yield this.handleSuccess(userCredential);
}
catch (err) {
this.handleError(err);
}
finally {
this.isLoading = false;
}
});
}
/**
* Update the profile (name + photo url) of the authenticated user in the
* firebase authentication feature (not in firestore)
*
* @param {?} name - the new name of the authenticated user
* @param {?} photoURL - the new photo url of the authenticated user
* @return {?}
*/
updateProfile(name, photoURL) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.afa.auth.currentUser.updateProfile({ displayName: name, photoURL: photoURL });
});
}
/**
* @return {?}
*/
deleteAccount() {
return __awaiter(this, void 0, void 0, function* () {
return yield this.afa.auth.currentUser.delete();
});
}
/**
* @param {?} user
* @return {?}
*/
parseUserInfo(user) {
return {
uid: user.uid,
displayName: user.displayName,
email: user.email,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL,
providerId: user.providerData.length > 0 ? user.providerData[0].providerId : null
};
}
/**
* @return {?}
*/
getUserPhotoUrl() {
/** @type {?} */
const user = this.afa.auth.currentUser;
if (!user) {
return;
}
else if (user.photoURL) {
return user.photoURL;
}
else if (user.emailVerified) {
return this.getPhotoPath(Accounts.CHECK);
}
else if (user.isAnonymous) {
return this.getPhotoPath(Accounts.OFF);
}
else {
return this.getPhotoPath(Accounts.NONE);
}
}
/**
* @param {?} image
* @return {?}
*/
getPhotoPath(image) {
return `assets/user/${image}.svg`;
}
/**
* @return {?}
*/
signInWithPhoneNumber() {
// todo: 3.1.18
}
/**
* @param {?} userCredential
* @return {?}
*/
handleSuccess(userCredential) {
return __awaiter(this, void 0, void 0, function* () {
yield this._fireStoreService.updateUserData(this.parseUserInfo(userCredential.user));
if (this.config.toastMessageOnAuthSuccess) {
this._snackBar.open(`Hallo ${userCredential.user.displayName ? userCredential.user.displayName : ''}!`, 'OK', { duration: 5000 });
}
this.onSuccessEmitter.next(userCredential.user);
});
}
/**
* @param {?} error
* @return {?}
*/
handleError(error) {
if (this.config.toastMessageOnAuthError) {
this._snackBar.open(error.message, 'OK', { duration: 5000 });
}
console.error(error);
this.onErrorEmitter.next(error);
}
}
AuthProcessService$$1.decorators = [
{ type: Injectable },
];
/** @nocollapse */
AuthProcessService$$1.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NgxAuthFirebaseUIConfigToken,] }] },
{ type: AngularFireAuth },
{ type: MatSnackBar },
{ type: FirestoreSyncService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class LegalityDialogComponent {
/**
* @param {?} dialogRef
* @param {?} data
*/
constructor(dialogRef, data) {
this.dialogRef = dialogRef;
this.data = data;
this._disableConfirmActionButton = false;
}
/**
* @return {?}
*/
get disableConfirmActionButton() {
if (this.data.tosUrl && this.data.privacyPolicyUrl) {
this._disableConfirmActionButton = !(this.checkTOS && this.checkPrivacyPolicy);
}
else if (this.data.tosUrl && !this.data.privacyPolicyUrl) {
this._disableConfirmActionButton = !this.checkTOS;
}
else if (!this.data.tosUrl && this.data.privacyPolicyUrl) {
this._disableConfirmActionButton = !this.checkPrivacyPolicy;
}
return this._disableConfirmActionButton;
}
/**
* @return {?}
*/
closeDialog() {
/** @type {?} */
const result = {
checked: !this.disableConfirmActionButton,
authProvider: this.data.authProvider
};
this.dialogRef.close(result);
}
}
LegalityDialogComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-auth-firebaseui-legality-dialog',
template: `
<h1 matDialogTitle>Legal requirements</h1>
<mat-dialog-content>
<div fxLayout="column" fxLayoutAlign="start">
<mat-checkbox *ngIf="this.data.tosUrl" [(ngModel)]="checkTOS">
I agree to the
<span> </span>
<a target="_blank"
[href]="this.data.tosUrl">
Terms of Service and Conditions
</a>
</mat-checkbox>
<mat-checkbox *ngIf="this.data.privacyPolicyUrl"
[(ngModel)]="checkPrivacyPolicy">
I have read and agree to the
<span> </span>
<a target="_blank"
[href]="this.data.privacyPolicyUrl">
Privacy
</a>
</mat-checkbox>
</div>
</mat-dialog-content>
<mat-dialog-actions>
<button id="decline-action"
mat-raised-button
matDialogClose
color="warn">Decline</button>
<button id="confirm-action"
mat-raised-button
color="primary"
[disabled]="disableConfirmActionButton"
(click)="closeDialog()">Confirm
</button>
</mat-dialog-actions>
`,
styles: [`
::ng-deep .mat-checkbox-label{display:flex;flex-wrap:wrap}mat-dialog-content div{margin-top:1.5rem}mat-dialog-actions{margin-top:1rem}
`]
},] },
];
/** @nocollapse */
LegalityDialogComponent.ctorParameters = () => [
{ type: MatDialogRef },
{ type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
];
var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/** @type {?} */
const EMAIL_REGEX = new RegExp(['^(([^<>()[\\]\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\.,;:\\s@\"]+)*)',
'|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.',
'[0-9]{1,3}\])|(([a-zA-Z\\-0-9]+\\.)+',
'[a-zA-Z]{2,}))$'].join(''));
/** @type {?} */
const PHONE_NUMBER_REGEX = new RegExp(/^\+(?:[0-9] ?){6,14}[0-9]$/);
class AuthComponent {
/**
* @param {?} platformId
* @param {?} auth
* @param {?} authProcess
* @param {?} dialog
*/
constructor(platformId, auth$$1, authProcess, dialog) {
this.platformId = platformId;
this.auth = auth$$1;
this.authProcess = authProcess;
this.dialog = dialog;
this.providers = AuthProvider$$1.ALL; // google, facebook, twitter, github as array or all as one single string
this.guestEnabled = true;
this.authProvider = AuthProvider$$1;
this.authenticationError = false;
this.passReset = false;
this.authProviders = AuthProvider$$1;
this.onSuccess = authProcess.onSuccessEmitter;
this.onError = authProcess.onErrorEmitter;
}
/**
* @return {?}
*/
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
this.onErrorSubscription = this.onError.subscribe(() => this.authenticationError = true);
}
this._initSignInFormGroupBuilder();
this._initSignUpFormGroupBuilder();
this._initResetPasswordFormGroupBuilder();
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.onErrorSubscription) {
this.onErrorSubscription.unsubscribe();
}
}
/**
* @return {?}
*/
get color() {
return this.authenticationError ? 'warn' : 'primary';
}
/**
* @return {?}
*/
createForgotPasswordTab() {
this.passwordResetWished = true;
setTimeout(() => this.tabIndex = 0, 100);
}
/**
* @param {?=} authProvider
* @return {?}
*/
openLegalityDialog(authProvider) {
if (this.tosUrl || this.privacyPolicyUrl) {
/** @type {?} */
const params = {
tosUrl: this.tosUrl,
privacyPolicyUrl: this.privacyPolicyUrl,
authProvider: authProvider
};
this.dialogRef = this.dialog.open(LegalityDialogComponent, { data: params });
this.dialogRef.afterClosed().subscribe((result) => {
console.log('this.dialogRef.afterClosed(): ', result);
if (result && result.checked) {
this._afterSignUpMiddleware(result.authProvider).then(() => this.signUpFormGroup.reset());
}
this.dialogRef = null;
});
}
else {
this._afterSignUpMiddleware(authProvider).then(() => this.signUpFormGroup.reset());
}
}
/**
* @return {?}
*/
signUp() {
return __awaiter$1(this, void 0, void 0, function* () {
return yield this.authProcess.signUp(this.signUpFormGroup.value.name, this.signUpFormGroup.value.email, this.signUpFormGroup.value.password);
});
}
/**
* @return {?}
*/
signUpAnonymously() {
return __awaiter$1(this, void 0, void 0, function* () {
return yield this.authProcess.signInWith(this.authProvider.ANONYMOUS);
});
}
/**
* @return {?}
*/
resetPassword() {
this.authProcess.resetPassword(this.resetPasswordEmailFormControl.value)
.then(() => this.passReset = true);
}
/**
* @return {?}
*/
_initSignInFormGroupBuilder() {
this.signInFormGroup = new FormGroup({});
this.signInFormGroup.registerControl('email', this.signInEmailFormControl = new FormControl('', [
Validators.required,
Validators.pattern(EMAIL_REGEX)
]));
this.signInFormGroup.registerControl('password', this.sigInPasswordFormControl = new FormControl('', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(25),
]));
}
/**
* @return {?}
*/
_initSignUpFormGroupBuilder() {
this.signUpFormGroup = new FormGroup({
name: this.sigUpNameFormControl = new FormControl('', [
Validators.required,
Validators.minLength(2),
Validators.maxLength(30),
]),
email: this.sigUpEmailFormControl = new FormControl('', [
Validators.required,
Validators.pattern(EMAIL_REGEX)
]),
password: this.sigUpPasswordFormControl = new FormControl('', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(25),
])
});
}
/**
* @return {?}
*/
_initResetPasswordFormGroupBuilder() {
this.resetPasswordFormGroup = new FormGroup({
email: this.resetPasswordEmailFormControl = new FormControl('', [
Validators.required,
Validators.pattern(EMAIL_REGEX)
])
});
}
/**
* @param {?=} authProvider
* @return {?}
*/
_afterSignUpMiddleware(authProvider) {
if (authProvider === this.authProvider.ANONYMOUS) {
return this.signUpAnonymously();
}
return this.signUp();
}
}
AuthComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-auth-firebaseui',
template: `
<mat-tab-group [color]="color" [selectedIndex]="tabIndex">
<!--Reset password tab-->
<mat-tab *ngIf="passwordResetWished" label="Reset Password">
<form [formGroup]="resetPasswordFormGroup" (ngSubmit)="resetPasswordFormGroup.valid && resetPassword()">
<mat-card>
<mat-card-header fxLayoutAlign="end">
<button mat-icon-button
[color]="color"
matTooltip="close"
matTooltipPosition="above"
(click)="passwordResetWished = false">
<mat-icon>close</mat-icon>
</button>
</mat-card-header>
<mat-card-content>
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>Reset e-mail address to password</mat-label>
<input matInput
[readonly]="passReset"
formControlName="email"
title="Reset e-mail address to password"
required>
<mat-icon matSuffix [color]="color">email</mat-icon>
<mat-error *ngIf="resetPasswordEmailFormControl.hasError('required')">
E-mail is required to reset the password!
</mat-error>
<mat-error *ngIf="resetPasswordEmailFormControl.hasError('pattern')">
Please enter a valid e-mail address
</mat-error>
</mat-form-field>
</mat-card-content>
<mat-card-actions fxLayoutAlign="center">
<button mat-raised-button
type="submit"
[color]="color"
[disabled]="passReset">
Reset
</button>
</mat-card-actions>
<mat-card-footer *ngIf="passReset" fxLayoutAlign="center">
<p>Reset requested. Check your e-mail instructions.</p>
</mat-card-footer>
<mat-card-footer>
<mat-progress-bar *ngIf="authProcess.isLoading" mode="indeterminate"></mat-progress-bar>
</mat-card-footer>
</mat-card>
</form>
</mat-tab>
<!--Sign in tab-->
<mat-tab label="Sign in">
<mat-card>
<mat-card-title>Signing in</mat-card-title>
<mat-card-content>
<form [formGroup]="signInFormGroup"
(ngSubmit)="signInFormGroup.valid &&
authProcess.signInWith
(authProviders.EmailAndPassword,signInFormGroup.value.email,signInFormGroup.value.password)">
<div fxLayout="column" fxLayoutAlign="center">
<mat-form-field [appearance]="appearance">
<mat-label>E-mail</mat-label>
<input matInput
placeholder="E-mail"
formControlName="email"
required>
<mat-icon matSuffix [color]="color">email</mat-icon>
<mat-error *ngIf="signInEmailFormControl.hasError('required')">
E-mail is required
</mat-error>
<mat-error *ngIf="signInEmailFormControl.hasError('pattern')">
Please enter a valid e-mail address
</mat-error>
</mat-form-field>
<mat-form-field [appearance]="appearance">
<mat-label>Password</mat-label>
<input matInput
type="current-password"
placeholder="Password"
minlength="6"
maxlength="25"
formControlName="password"
required>
<mat-icon matSuffix [color]="color">lock</mat-icon>
<mat-hint align="end" aria-live="polite">
{{signInFormGroup.value.password.length}} / 25
</mat-hint>
<mat-error *ngIf="sigInPasswordFormControl.hasError('required')">
Please do not forget the password
</mat-error>
<mat-error *ngIf="sigInPasswordFormControl.hasError('minlength')">
The password must be at least 6 characters long.
</mat-error>
<mat-error *ngIf="sigInPasswordFormControl.hasError('maxlength')">
The password must not exceed 25 characters
</mat-error>
</mat-form-field>
<button mat-raised-button
style="margin-top: 20px"
type="submit"
class="space-top"
[color]="color">
Log In
</button>
</div>
</form>
<div fxLayoutAlign="center">
<button mat-button
class="space-top"
[color]="color"
(click)="createForgotPasswordTab()">
Forgot Password?
</button>
</div>
</mat-card-content>
<mat-card-footer *ngIf="authProcess.isLoading">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</mat-card-footer>
</mat-card>
</mat-tab>
<!--tab register-->
<mat-tab label="Register">
<mat-card>
<mat-card-title>Registration</mat-card-title>
<div *ngIf="!authProcess.emailConfirmationSent;then register else confirm"></div>
<ng-template #register>
<mat-card-content fxLayout="column" fxLayoutAlign="center">
<form [formGroup]="signUpFormGroup" (ngSubmit)="signUpFormGroup.valid &&
authProcess.signUp
(signUpFormGroup.value.name,signUpFormGroup.value.email,signUpFormGroup.value.password)">
<div fxLayout="column" fxLayoutAlign="center">
<!--name-->
<mat-form-field [appearance]="appearance">
<!--labels will work only with @angular/material@6.2.0 -->
<mat-label>Name</mat-label>
<input matInput
placeholder="Name"
minlength="2"
maxlength="30"
[formControl]="sigUpNameFormControl"
required>
<mat-icon matSuffix [color]="color">person</mat-icon>
<mat-hint align="end" aria-live="polite">
{{signUpFormGroup.value.name?.length}} / 25
</mat-hint>
<mat-error *ngIf="sigUpNameFormControl.hasError('required')">
Name is required
</mat-error>
<mat-error *ngIf="sigUpPasswordFormControl.hasError('minlength')">
The name is too short!
</mat-error>
<mat-error *ngIf="sigUpPasswordFormControl.hasError('maxlength')">
The name is too long!
</mat-error>
</mat-form-field>
<!--email-->
<mat-form-field [appearance]="appearance">
<mat-label>E-mail</mat-label>
<input matInput
placeholder="E-mail"
type="email"
[formControl]="sigUpEmailFormControl">
<mat-icon matSuffix [color]="color">email</mat-icon>
<mat-error *ngIf="sigUpEmailFormControl.hasError('required')">
E-mail is required
</mat-error>
<mat-error *ngIf="sigUpEmailFormControl.hasError('pattern')">
Please enter a valid e-mail address
</mat-error>
</mat-form-field>
<!--password-->
<div fxLayout="column">
<mat-form-field [appearance]="appearance">
<mat-label>Password</mat-label>
<input matInput
type="password"
placeholder="password"
name="password"
[formControl]="sigUpPasswordFormControl"
required>
<mat-icon matSuffix [color]="color">lock</mat-icon>
<mat-hint align="end" aria-live="polite">
{{signUpFormGroup.value.password?.length}} / 25
</mat-hint>
<mat-error *ngIf="sigUpPasswordFormControl.hasError('required')" class="cut-text">
Please do not forget the password
</mat-error>
<mat-error *ngIf="sigUpPasswordFormControl.hasError('minlength')" class="cut-text">
The password must be at least 6 characters long.
</mat-error>
<mat-error *ngIf="sigUpPasswordFormControl.hasError('maxlength')" class="cut-text">
The password can not be longer than 25 characters.
</mat-error>
</mat-form-field>
</div>
<button mat-raised-button
style="margin-top: 20px"
type="submit"
[color]="color">
Register
</button>
</div>
</form>
<button *ngIf="guestEnabled"
mat-button
style="margin-top: 20px"
[color]="color"
(click)="openLegalityDialog(authProvider.ANONYMOUS)">
<mat-icon>fingerprint</mat-icon>
continue as guest
</button>
</mat-card-content>
<mat-card-footer *ngIf="authProcess.isLoading">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</mat-card-footer>
</ng-template>
<!--confirm template-->
<ng-template #confirm>
<ngx-auth-firebaseui-email-confirmation [email]="authProcess.emailToConfirm"
[goBackURL]="goBackURL">
</ngx-auth-firebaseui-email-confirmation>
</ng-template>
</mat-card>
</mat-tab>
</mat-tab-group>
<mat-divider></mat-divider>
<ngx-auth-firebaseui-providers [providers]="providers"></ngx-auth-firebaseui-providers>
`,
styles: [`
.mat-card{margin:2rem}.space-top{margin-top:.5rem}.full-width{width:100%}.cut-text{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}
`]
},] },
];
/** @nocollapse */
AuthComponent.ctorParameters = () => [
{ type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
{ type: AngularFireAuth },
{ type: AuthProcessService$$1 },
{ type: MatDialog }
];
AuthComponent.propDecorators = {
providers: [{ type: Input }],
appearance: [{ type: Input }],
tabIndex: [{ type: Input }],
guestEnabled: [{ type: Input }],
tosUrl: [{ type: Input }],
privacyPolicyUrl: [{ type: Input }],
goBackURL: [{ type: Input }],
onSuccess: [{ type: Output }],
onError: [{ type: Output }]
};
var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
class UserComponent {
/**
* @param {?} auth
* @param {?} authProcess
* @param {?} _fireStoreService
* @param {?} snackBar
*/
constructor(auth$$1, authProcess, _fireStoreService, snackBar) {
this.auth = auth$$1;
this.authProcess = authProcess;
this._fireStoreService = _fireStoreService;
this.snackBar = snackBar;
this.onAccountDeleted = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
}
/**
* @return {?}
*/
initUpdateFormGroup() {
/** @type {?} */
const currentUser = this.auth.auth.currentUser;
this.updateFormGroup = new FormGroup({
name: this.updateNameFormControl = new FormControl({ value: currentUser.displayName, disabled: true }, [
Validators.required,
Validators.minLength(2),
Validators.maxLength(25),
]),
email: this.updateEmailFormControl = new FormControl({ value: currentUser.email, disabled: true }, [
Validators.required,
Validators.pattern(EMAIL_REGEX)
]),
phoneNumber: this.updatePhoneNumberFormControl = new FormControl('', [Validators.pattern(PHONE_NUMBER_REGEX)])
});
this.updateFormGroup.enable();
}
/**
* @return {?}
*/
changeEditMode() {
this.editMode = !this.editMode;
this.editMode ? this.initUpdateFormGroup() : this.reset();
}
/**
* @return {?}
*/
reset() {
this.updateFormGroup.reset();
this.updateFormGroup.disable();
this.updateFormGroup = null;
}
// todo: 31.3.18
/**
* @return {?}
*/
save() {
return __awaiter$2(this, void 0, void 0, function* () {
if (this.updateFormGroup.dirty) {
/** @type {?} */
const user = this.auth.auth.currentUser;
// user.updateProfile()
// user.updateEmail()
console.log('form = ', this.updateFormGroup);
/** @type {?} */
const snackBarMsg = [];
try {
if (this.updateNameFormControl.dirty) {
yield user.updateProfile({ displayName: this.updateNameFormControl.value, photoURL: null });
snackBarMsg.push(`your name has been update to ${user.displayName}`);
}
if (this.updateEmailFormControl.dirty) {
yield user.updateEmail(this.updateEmailFormControl.value);
snackBarMsg.push(`your email has been update to ${user.email}`);
}
if (this.updatePhoneNumberFormControl.dirty) {
yield user.updatePhoneNumber(this.updatePhoneNumberFormControl.value);
console.log('phone number = ', this.updatePhoneNumberFormControl.value);
snackBarMsg.push(`your phone number has been update to ${user.phoneNumber}`);
}
yield this._fireStoreService.updateUserData(this.authProcess.parseUserInfo(user));
}
catch (error) {
error.message ? this.snackBar.open(error.message, 'Ok') : this.snackBar.open(error, 'Ok');
console.error(error);
console.error(error.code);
console.error(error.message);
}
if (snackBarMsg.length > 0) {
this.snackBar.open(snackBarMsg.join('\\n'), 'Ok');
}
// this.updateFormGroup.reset();
}
this.editMode = false;
});
}
/**
* Delete the account of the current firebase user
*
* On Success, emit the <onAccountDeleted> event and toast a msg!#
* Otherwise, log the and toast and error msg!
*
* @return {?}
*/
deleteAccount() {
return __awaiter$2(this, void 0, void 0, function* () {
try {
/** @type {?} */
const user = this.auth.auth.currentUser;
yield this.authProcess.deleteAccount();
yield this._fireStoreService.deleteUserData(user.uid);
this.onAccountDeleted.emit();
this.editMode = false;
this.snackBar.open('Your account has been successfully deleted!', 'OK', {
duration: 5000
});
}
catch (error) {
console.log('Error while delete user\'s account', error);
this.snackBar.open('Error occurred while deleting your account!', 'OK', {
duration: 5000
});
}
});
}
}
UserComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-auth-firebaseui-user',
template: `
<div *ngIf="auth.authState| async as user; then authenticated else none">
</div>
<ng-template #authenticated>
<mat-card *ngIf="auth.user | async as user">
<!--<form [formGroup]="updateFormGroup" >-->
<!--card header-->
<mat-card-header fxLayout="column" fxLayoutAlign="center center">
<img mat-card-avatar [src]="authProcess?.getUserPhotoUrl()">
<div *ngIf="user.emailVerified; then emailVerified else emailNotVerified"></div>
<ng-template #emailVerified>
<mat-icon color="primary"
matTooltip="email is verified"
matTooltipPosition="after">
verified_user
</mat-icon>
</ng-template>
<ng-template #emailNotVerified>
<mat-icon color="warn"
matTooltip="email is not verified"
matTooltipPosition="after">
warning
</mat-icon>
</ng-template>
</mat-card-header>
<!--card content-->
<mat-card-content *ngIf="editMode; then edit else readonly">
</mat-card-content>
<ng-template #edit>
<form [formGroup]="updateFormGroup" (submit)="save()">
<mat-card-content fxLayout="column" fxLayoutAlign="center center">
<div fxLayoutAlign="center">
<button mat-raised-button color="warn" class="edit-button"
(click)="changeEditMode()">
cancel
</button>
</div>
<!--name-->
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>Name</mat-label>
<input matInput
placeholder="Name"
[formControl]="updateNameFormControl"
[value]="user.displayName">
<mat-icon matSuffix>person</mat-icon>
<mat-hint align="end" aria-live="polite">
{{updateNameFormControl.value.length}} / 25
</mat-hint>
<mat-error *ngIf="updateNameFormControl.hasError('required')">
Name is required
</mat-error>
</mat-form-field>
<!--email-->
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>E-mail</mat-label>
<input matInput
placeholder="E-mail"
[formControl]="updateEmailFormControl"
[value]="user.email">
<mat-icon matSuffix>email</mat-icon>
<mat-error *ngIf="updateEmailFormControl.hasError('required')">
E-mail is required {{updateEmailFormControl.value}}
</mat-error>
<mat-error *ngIf="updateEmailFormControl.hasError('pattern')">
Please enter a valid e-mail address {{updateEmailFormControl.value}}
</mat-error>
</mat-form-field>
<!--phone number-->
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>Phone number</mat-label>
<input matInput
type="number"
placeholder="Phone number"
[formControl]="updatePhoneNumberFormControl"
[value]="user.phoneNumber">
<mat-icon matSuffix>phone</mat-icon>
<mat-hint align="end" aria-live="polite">
The phone number is international. Therefore, it should start with a + sign or 00,
followed by the country code, - and national number e.g: +49-12345678 or 0041-1234567890
NOTE : the phone number must be a valid phone credential !!
</mat-hint>
<mat-error *ngIf="updatePhoneNumberFormControl.hasError('pattern')">
Please enter a valid phone number
</mat-error>
</mat-form-field>
</mat-card-content>
<mat-card-actions fxLayout="column">
<button mat-button
color="primary"
type="submit">
Save changes
</button>
</mat-card-actions>
</form>
</ng-template>
<ng-template #readonly>
<div fxLayoutAlign="center">
<button mat-raised-button color="primary" class="edit-button"
(click)="changeEditMode()">
edit
</button>
</div>
<!--name-->
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>Name</mat-label>
<input matInput
placeholder="Name"
[value]="user.displayName"
[disabled]="!editMode">
<mat-icon matSuffix color="primary">person</mat-icon>
</mat-form-field>
<!--email-->
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>E-mail</mat-label>
<input matInput
placeholder="E-mail" [value]="user.email"
[disabled]="!editMode">
<mat-icon matSuffix color="primary">email</mat-icon>
</mat-form-field>
<!--phone number-->
<mat-form-field class="full-width" [appearance]="appearance">
<mat-label>Phone number</mat-label>
<input matInput
placeholder="Phone number"
[value]="user.phoneNumber"
[disabled]="!editMode">
<mat-icon matSuffix color="primary">phone</mat-icon>
</mat-form-field>
<mat-card-actions fxLayout="column">
<button mat-button color="primary" (click)="auth.auth.signOut()">Sign out</button>
<button mat-button color="warn" (click)="deleteAccount()">Delete account</button>
</mat-card-actions>
</ng-template>
</mat-card>
</ng-template>
<ng-template #none>
<mat-card class="none-card" fxLayout="row" fxLayoutAlign="center center">
<mat-card-content fxLayout="row" fxLayoutAlign="center center">
<mat-icon color="accent">warning</mat-icon>
<span>You are not logged in!</span>
</mat-card-content>
</mat-card>
</ng-template>
`,
styles: [`
.edit-button{margin:1rem}.full-width{width:100%}.cut-text{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.none-card{min-height:430px}.none-card span{font-size:24px;text-align:center;color:rgba(0,0,0,.54)}
`]
},] },
];
/** @nocollapse */
UserComponent.ctorParameters = () => [
{ type: AngularFireAuth },
{ type: AuthProcessService$$1 },
{ type: FirestoreSyncService },
{ type: MatSnackBar }
];
UserComponent.propDecorators = {
editMode: [{ type: Input }],
appearance: [{ type: Input }],
onAccountDeleted: [{ type: Output }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @enum {string} */
const Theme = {
DEFAULT: 'default',
CLASSIC: 'classic',
STROKED: 'stroked',
FAB: 'fab',
MINI_FAB: 'mini-fab',
RAISED: 'raised',
};
/** @enum {string} */
const Layout = {
ROW: 'row',
COLUMN: 'column',
};
class AuthProvidersComponent {
/**
* @param {?} authProcess
* @param {?} _iconRegistry
* @param {?} _sanitizer
*/
constructor(authProcess, _iconRegistry, _sanitizer) {
this.authProcess = authProcess;
this._iconRegistry = _iconRegistry;
this._sanitizer = _sanitizer;
// theme: string = Theme.DEFAULT;
this.layout = Layout.ROW;
this.providers = AuthProvider$$1.ALL; // google, facebook, twitter, github
// google, facebook, twitter, github
this.themes = Theme;
this.authProvider = AuthProvider$$1;
_iconRegistry
.addSvgIcon('google', _sanitizer.bypassSecurityTrustResourceUrl('/assets/mdi/google.svg'))
.addSvgIcon('google-colored', _sanitizer.bypassSecurityTrustResourceUrl('/assets/google.svg'))
.addSvgIcon('facebook', _sanitizer.bypassSecurityTrustResourceUrl('/assets/mdi/facebook.svg'))
.addSvgIcon('twitter', _sanitizer.bypassSecurityTrustResourceUrl('/assets/mdi/twitter.svg'))
.addSvgIcon('github', _sanitizer.bypassSecurityTrustResourceUrl('/assets/mdi/github-circle.svg'))
.addSvgIcon('phone', _sanitizer.bypassSecurityTrustResourceUrl('/assets/phone.svg'));
}
}
AuthProvidersComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-auth-firebaseui-providers',
template: `
<div [ngSwitch]="theme">
<!--default icon buttons-->
<div *ngSwitchDefault
[fxLayout]="layout"
fxLayout.xs="column"
[fxLayoutAlign]="layout == 'row' ? 'space-around center' : 'stretch'">
<button *ngIf="providers === authProvider.ALL || providers.includes(authProvider.Google)"
mat-button
[ngClass.xs]="{'space-full-xs':true}"
(click)="authProcess.signInWith(authProvider.Google)">
<mat-icon svgIcon="google-colored"></mat-icon>
Google
</button>
<button *ngIf="providers === authProvider.ALL || providers.includes(authProvider.Facebook)"
mat-button
class="facebook-filled"
[ngClass.xs]="{'space-full-xs':true}"
(click)="authProcess.signInWith(authProvider.Facebook)">
<mat-icon svgIcon="facebook"></mat-icon>
Facebook
</button>
<button *ngIf="providers === authProvider.ALL || providers.includes(authProvider.Twitter)"
mat-button
class="twitter-filled"
[ngClass.xs]="{'space-full-xs':true}"
(click)="authProcess.signInWith(authProvider.Twitter)">
<mat-icon svgIcon="twitter"></mat-icon>
Twitter
</button>
<button *ngIf="providers === authProvider.ALL || providers.includes(authProvider.Github)"
mat-button
[ngCl