Skip to content

Commit 02eae5e

Browse files
committed
Redirect strategy
1 parent a72ccab commit 02eae5e

File tree

3 files changed

+174
-33
lines changed

3 files changed

+174
-33
lines changed

packages-exp/auth-exp/demo/src/index.js

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import {
3131
createUserWithEmailAndPassword,
3232
EmailAuthProvider,
3333
fetchSignInMethodsForEmail,
34-
getMultiFactorResolver,
3534
indexedDBLocalPersistence,
3635
initializeAuth,
3736
inMemoryPersistence,
@@ -54,10 +53,15 @@ import {
5453
updatePassword,
5554
updateProfile,
5655
verifyPasswordResetCode,
56+
getMultiFactorResolver,
5757
OAuthProvider,
5858
signInWithPopup,
5959
linkWithPopup,
6060
reauthenticateWithPopup,
61+
signInWithRedirect,
62+
linkWithRedirect,
63+
reauthenticateWithRedirect,
64+
getRedirectResult,
6165
browserPopupRedirectResolver
6266
} from '@firebase/auth-exp/dist/index.browser';
6367

@@ -1240,12 +1244,16 @@ function signInWithPopupRedirect(provider) {
12401244
const glob = {
12411245
signInWithPopup,
12421246
linkWithPopup,
1243-
reauthenticateWithPopup
1244-
};
1247+
reauthenticateWithPopup,
1248+
signInWithRedirect,
1249+
linkWithRedirect,
1250+
reauthenticateWithRedirect
1251+
}
12451252
let action = $('input[name=popup-redirect-action]:checked').val();
12461253
let type = $('input[name=popup-redirect-type]:checked').val();
12471254
let method = null;
12481255
let inst = null;
1256+
12491257
if (action == 'link' || action == 'reauthenticate') {
12501258
if (!activeUser()) {
12511259
alertError('No user logged in.');
@@ -1310,13 +1318,12 @@ function signInWithPopupRedirect(provider) {
13101318
onAuthError
13111319
);
13121320
} else {
1313-
alertNotImplemented();
1314-
// try {
1315-
// inst[method](provider).catch(onAuthError);
1316-
// } catch (error) {
1317-
// console.log('Error while calling ' + method);
1318-
// console.error(error);
1319-
// }
1321+
try {
1322+
glob[method](inst, provider, browserPopupRedirectResolver).catch(onAuthError);
1323+
} catch (error) {
1324+
console.log('Error while calling ' + method);
1325+
console.error(error);
1326+
}
13201327
}
13211328
}
13221329

@@ -1334,24 +1341,23 @@ function onAuthUserCredentialSuccess(result) {
13341341
* Displays redirect result.
13351342
*/
13361343
function onGetRedirectResult() {
1337-
alertNotImplemented();
1338-
// auth.getRedirectResult().then(function(response) {
1339-
// log('Redirect results:');
1340-
// if (response.credential) {
1341-
// log('Credential:');
1342-
// log(response.credential);
1343-
// } else {
1344-
// log('No credential');
1345-
// }
1346-
// if (response.user) {
1347-
// log('User\'s id:');
1348-
// log(response.user.uid);
1349-
// } else {
1350-
// log('No user');
1351-
// }
1352-
// logAdditionalUserInfo(response);
1353-
// console.log(response);
1354-
// }, onAuthError);
1344+
getRedirectResult(auth, browserPopupRedirectResolver).then(function(response) {
1345+
log('Redirect results:');
1346+
if (response.credential) {
1347+
log('Credential:');
1348+
log(response.credential);
1349+
} else {
1350+
log('No credential');
1351+
}
1352+
if (response.user) {
1353+
log('User\'s id:');
1354+
log(response.user.uid);
1355+
} else {
1356+
log('No user');
1357+
}
1358+
logAdditionalUserInfo(response);
1359+
console.log(response);
1360+
}, onAuthError);
13551361
}
13561362

13571363
/**
@@ -1764,11 +1770,10 @@ function initApp() {
17641770
}
17651771

17661772
// We check for redirect result to refresh user's data.
1767-
// TODO: redirect result
1768-
// auth.getRedirectResult().then(function(response) {
1769-
// refreshUserData();
1770-
// logAdditionalUserInfo(response);
1771-
// }, onAuthError);
1773+
getRedirectResult(auth, browserPopupRedirectResolver).then(function(response) {
1774+
refreshUserData();
1775+
logAdditionalUserInfo(response);
1776+
}, onAuthError);
17721777

17731778
// Bootstrap tooltips.
17741779
$('[data-toggle="tooltip"]').tooltip();

packages-exp/auth-exp/index.browser.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ export {
3838
linkWithPopup,
3939
reauthenticateWithPopup
4040
} from './src/core/strategies/popup';
41+
export {
42+
signInWithRedirect,
43+
linkWithRedirect,
44+
reauthenticateWithRedirect,
45+
getRedirectResult
46+
} from './src/core/strategies/redirect';
4147

4248
// platform_browser
4349
export { RecaptchaVerifier } from './src/platform_browser/recaptcha/recaptcha_verifier';
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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

Comments
 (0)