Passed
Push — master ( 57ea89...92a34c )
by Miloš
03:10
created

BaseAuthService.setUserInitializedIfNotAlready   A

Complexity

Conditions 2

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
1
import { Injectable } from "@angular/core";
2
import { AngularFireAuth } from "@angular/fire/auth";
3
import { ActivatedRoute, Router } from "@angular/router";
4
import { Platform } from "@ionic/angular";
5
import { auth as firebaseAuth, User as FirebaseUser } from "firebase";
6
import { auth } from "firebase/app";
7
import { BehaviorSubject, Observable, Subscription } from "rxjs";
8
import { UniFirebaseLoginConfig } from "../config/uni-firebase-login-config";
9
import { UniFirebaseLoginConfigProvider } from "../config/uni-firebase-login-config-provider";
10
import { UserModel } from "../model/user-model";
11
import { AuthProvider } from "../providers/auth-provider";
12
import { IAuthProvider } from "../providers/i-auth-provider";
13
import { AuthStorageProvider } from "../storage/auth-storage-provider.service";
14
import { IAuthService } from "./i-auth-service";
15
16
@Injectable({
17
    providedIn: "root",
18
})
19
export class BaseAuthService<User extends UserModel = UserModel>
20
    implements IAuthService<User> {
21
    public get user(): User | null {
22
        return this._user.getValue();
23
    }
24
25
    public get user$(): Observable<User | null> {
26
        return this._user;
27
    }
28
29
    public get userInitialized(): boolean {
30
        return this._userInitialized.getValue();
31
    }
32
33
    public get userInitialized$(): Observable<boolean> {
34
        return this._userInitialized;
35
    }
36
37
    public get currentFirebaseUser(): FirebaseUser | null {
38
        return firebaseAuth().currentUser;
39
    }
40
41
    protected config: UniFirebaseLoginConfig;
42
    protected _user: BehaviorSubject<User | null> = new BehaviorSubject<User | null>(
43
        null,
44
    );
45
    protected _userInitialized: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
46
    private userDataSubscription: Subscription | undefined;
47
48
    public constructor(
49
        protected router: Router,
50
        protected route: ActivatedRoute,
51
        protected platform: Platform,
52
        protected authProvider: AuthProvider,
53
        protected authStorageProvider: AuthStorageProvider<User>,
54
        protected angularFireAuth: AngularFireAuth,
55
        configProvider: UniFirebaseLoginConfigProvider,
56
    ) {
57
        this.config = configProvider.config;
58
        this.subscribeUserChanges();
59
    }
60
61
    public async signInByProvider(
62
        provider: IAuthProvider,
63
    ): Promise<auth.UserCredential | null> {
64
        const credential = await provider.handleLogin();
65
        if (
66
            this.config.storage !== false &&
67
            credential &&
68
            credential.user !== null
69
        ) {
70
            await this.authStorageProvider
71
                .getProvider()
72
                .updateStoredDataByFirebaseUser(credential.user);
73
        }
74
        return credential;
75
    }
76
77
    public async signInAnonymously(): Promise<auth.UserCredential | null> {
78
        return this.signInByProvider(
79
            this.authProvider.authAnonymous,
80
        );
81
    }
82
83
    public async signInViaEmail(): Promise<auth.UserCredential | null> {
84
        return this.signInByProvider(
85
            this.authProvider.authEmail,
86
        );
87
    }
88
89
    public async signInViaFacebook(): Promise<auth.UserCredential | null> {
90
        return this.signInByProvider(
91
            this.authProvider.authFacebook,
92
        );
93
    }
94
95
    public async signInViaGithub(): Promise<auth.UserCredential | null> {
96
        return this.signInByProvider(
97
            this.authProvider.authGithub,
98
        );
99
    }
100
101
    public async signInViaGoogle(): Promise<auth.UserCredential | null> {
102
        return this.signInByProvider(
103
            this.authProvider.authGoogle,
104
        );
105
    }
106
107
    public async signInViaPhone(): Promise<auth.UserCredential | null> {
108
        return this.signInByProvider(
109
            this.authProvider.authPhone,
110
        );
111
    }
112
113
    public async signInViaTwitter(): Promise<auth.UserCredential | null> {
114
        return this.signInByProvider(
115
            this.authProvider.authTwitter,
116
        );
117
    }
118
119
    /**
120
     * Handle sign out request
121
     */
122
    public async signOut(): Promise<void> {
123
        const currentUser = auth().currentUser;
124
125
        if (currentUser) {
126
            const providers = this.authProvider.getProvidersByUser(currentUser);
127
128
            for (const provider of providers) {
129
                await provider.handleSignOut();
130
            }
131
        }
132
    }
133
134
    public async updateUserData(user: User) {
135
        await this.authStorageProvider
136
            .getProvider()
137
            .updateStoredDataByUser(user);
138
    }
139
140
    private subscribeUserChanges(): void {
141
        this.angularFireAuth.authState.subscribe((user: any) => {
142
            if (user) {
143
                if (this.userDataSubscription) {
144
                    this.userDataSubscription.unsubscribe();
145
                }
146
                this.userDataSubscription = this.authStorageProvider
147
                    .getProvider()
148
                    .subscribeUserDataFromStorageByFirebaseUser(user)
149
                    .subscribe((resultUser: User | null) => {
150
                        this._user.next(resultUser);
151
                        this.setUserInitializedIfNotAlready();
152
                    });
153
            } else {
154
                // Logged out
155
                this._user.next(null);
156
                this.setUserInitializedIfNotAlready();
157
            }
158
        });
159
    }
160
161
    private setUserInitializedIfNotAlready() {
162
        if (!this._userInitialized.getValue()) {
163
            this._userInitialized.next(true);
164
        }
165
    }
166
}
167