1
+ /**
2
+ * @license
3
+ * Copyright 2020 Google LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import * as externs from '@firebase/auth-types-exp' ;
19
+
20
+ import { Auth } from '../../model/auth' ;
21
+ import { AuthEvent , AuthEventType , PopupRedirectResolver } from '../../model/popup_redirect' ;
22
+ import { User , UserCredential } from '../../model/user' ;
23
+ import { _assertLinkedStatus } from '../user/link_unlink' ;
24
+ import { _generateEventId } from '../util/event_id' ;
25
+ import { _getInstance } from '../util/instantiator' ;
26
+ import { AbstractPopupRedirectOperation } from './abstract_popup_redirect_operation' ;
27
+
28
+ export async function signInWithRedirect (
29
+ authExtern : externs . Auth ,
30
+ provider : externs . AuthProvider ,
31
+ resolverExtern : externs . PopupRedirectResolver
32
+ ) : Promise < never > {
33
+ const auth = authExtern as Auth ;
34
+ const resolver : PopupRedirectResolver = _getInstance ( resolverExtern ) ;
35
+
36
+ return resolver . _openRedirect ( auth , provider , AuthEventType . SIGN_IN_VIA_REDIRECT ) ;
37
+ }
38
+
39
+ export async function reauthenticateWithRedirect (
40
+ userExtern : externs . User ,
41
+ provider : externs . AuthProvider ,
42
+ resolverExtern : externs . PopupRedirectResolver
43
+ ) : Promise < never > {
44
+ const user = userExtern as User ;
45
+ const resolver : PopupRedirectResolver = _getInstance ( resolverExtern ) ;
46
+
47
+ const eventId = _generateEventId ( `${ user . uid } :::` ) ;
48
+ user . _redirectEventId = eventId ;
49
+ await user . auth . _setRedirectUser ( user ) ;
50
+
51
+ return resolver . _openRedirect ( user . auth , provider , AuthEventType . REAUTH_VIA_REDIRECT , eventId ) ;
52
+ }
53
+
54
+ export async function linkWithRedirect (
55
+ userExtern : externs . User ,
56
+ provider : externs . AuthProvider ,
57
+ resolverExtern : externs . PopupRedirectResolver
58
+ ) : Promise < never > {
59
+ const user = userExtern as User ;
60
+ const resolver : PopupRedirectResolver = _getInstance ( resolverExtern ) ;
61
+
62
+ await _assertLinkedStatus ( false , user , provider . providerId ) ;
63
+
64
+ const eventId = _generateEventId ( `${ user . uid } :::` ) ;
65
+ user . _redirectEventId = eventId ;
66
+ await user . auth . _setRedirectUser ( user ) ;
67
+
68
+ return resolver . _openRedirect ( user . auth , provider , AuthEventType . LINK_VIA_REDIRECT , eventId ) ;
69
+ }
70
+
71
+ export async function getRedirectResult ( authExtern : externs . Auth , resolverExtern : externs . PopupRedirectResolver ) : Promise < UserCredential > {
72
+ const auth = authExtern as Auth ;
73
+ const resolver : PopupRedirectResolver = _getInstance ( resolverExtern ) ;
74
+ const action = new RedirectAction ( auth , resolver ) ;
75
+ return action . execute ( ) ;
76
+ }
77
+
78
+
79
+ // We only get one redirect outcome for any one auth, so just store it
80
+ // in here.
81
+ const redirectOutcomeMap : Map < Auth , Promise < UserCredential > > = new Map ( ) ;
82
+
83
+ class RedirectAction extends AbstractPopupRedirectOperation {
84
+ eventId = null ;
85
+
86
+ constructor ( auth : Auth , resolver : PopupRedirectResolver ) {
87
+ super ( auth , [
88
+ AuthEventType . SIGN_IN_VIA_REDIRECT ,
89
+ AuthEventType . LINK_VIA_REDIRECT ,
90
+ AuthEventType . REAUTH_VIA_REDIRECT ,
91
+ ] ,
92
+ resolver ) ;
93
+ }
94
+
95
+ /**
96
+ * Override the execute function; if we already have a redirect result, then
97
+ * just return it.
98
+ */
99
+ async execute ( ) : Promise < UserCredential > {
100
+ let readyOutcome = redirectOutcomeMap . get ( this . auth ) ;
101
+ if ( ! readyOutcome ) {
102
+ readyOutcome = super . execute ( ) ;
103
+ redirectOutcomeMap . set ( this . auth , readyOutcome ) ;
104
+ }
105
+
106
+ return readyOutcome ;
107
+ }
108
+
109
+ async onAuthEvent ( event : AuthEvent ) : Promise < void > {
110
+ if ( event . type === AuthEventType . SIGN_IN_VIA_REDIRECT ) {
111
+ return super . onAuthEvent ( event ) ;
112
+ }
113
+
114
+ if ( event . eventId ) {
115
+ const user = this . auth . _redirectUserForId ( event . eventId ) ;
116
+ // TODO(samgho): What if user is null?
117
+ if ( user ) {
118
+ this . user = user ;
119
+ return super . onAuthEvent ( event ) ;
120
+ }
121
+ }
122
+ }
123
+
124
+ async onExecution ( ) : Promise < void > {
125
+ }
126
+
127
+ cleanUp ( ) : void {
128
+
129
+ }
130
+ }
0 commit comments