Skip to content

Commit dee832b

Browse files
committed
Broken
1 parent d91e449 commit dee832b

File tree

2 files changed

+72
-27
lines changed

2 files changed

+72
-27
lines changed

packages-exp/auth-compat-exp/src/user_credential.ts

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,80 @@
1717

1818
import * as exp from '@firebase/auth-exp/internal';
1919
import * as compat from '@firebase/auth-types';
20+
import { FirebaseError } from '@firebase/util';
2021
import { User } from './user';
2122

23+
const enum CredentialFrom {
24+
ERROR = 'credentialFromError',
25+
RESULT = 'credentialFromResult',
26+
}
27+
2228
function credentialFromResponse(
2329
userCredential: exp.UserCredentialInternal
2430
): exp.AuthCredential | null {
25-
const { providerId, _tokenResponse } = userCredential;
31+
return credentialFromObject(userCredential);
32+
}
33+
34+
function modifyError(
35+
auth: exp.Auth, e: FirebaseError,
36+
): void {
37+
// The response contains all fields from the server which may or may not
38+
// actually match the underlying type
39+
const response = (e.customData as exp.TaggedWithTokenResponse|undefined)?._tokenResponse as unknown as Record<string, string>;
40+
if (e.code === 'auth/multi-factor-auth-required') {
41+
const mfaErr = e as compat.MultiFactorError;
42+
mfaErr.resolver = exp.getMultiFactorResolver(auth, e as any);
43+
} else if (response) {
44+
const credential = credentialFromObject(e);
45+
const credErr = e as compat.AuthError;
46+
if (credential) {
47+
credErr.credential = credential;
48+
credErr.tenantId = response.tenantId || undefined;
49+
credErr.email = response.email || undefined;
50+
credErr.phoneNumber = response.phoneNumber || undefined;
51+
}
52+
}
53+
}
54+
55+
function credentialFromObject(object: FirebaseError|exp.UserCredential): exp.AuthCredential|null {
56+
const {_tokenResponse} = (object instanceof FirebaseError ? object.customData : object) as exp.TaggedWithTokenResponse;
2657
if (!_tokenResponse) {
2758
return null;
2859
}
60+
61+
const fn = object instanceof FirebaseError ? CredentialFrom.ERROR : CredentialFrom.RESULT;
62+
2963
// Handle phone Auth credential responses, as they have a different format
30-
// from other backend responses (i.e. no providerId).
31-
if ('temporaryProof' in _tokenResponse && 'phoneNumber' in _tokenResponse) {
32-
return exp.PhoneAuthProvider.credentialFromResult(userCredential);
64+
// from other backend responses (i.e. no providerId). This is also only the
65+
// case for user credentials (does not work for errors).
66+
if (!(object instanceof FirebaseError)) {
67+
if ('temporaryProof' in _tokenResponse && 'phoneNumber' in _tokenResponse) {
68+
return exp.PhoneAuthProvider.credentialFromResult(object);
69+
}
3370
}
71+
72+
const providerId = _tokenResponse.providerId;
73+
3474
// Email and password is not supported as there is no situation where the
3575
// server would return the password to the client.
3676
if (!providerId || providerId === exp.ProviderId.PASSWORD) {
3777
return null;
3878
}
3979

80+
// We know for a fact that the function will match the value type
81+
// (based on the declaration of fn). We will therefore cast object to a
82+
// meaningless type to bypass the type system
83+
const castObject = object as exp.UserCredential & FirebaseError;
84+
4085
switch (providerId) {
4186
case exp.ProviderId.GOOGLE:
42-
return exp.GoogleAuthProvider.credentialFromResult(userCredential);
87+
return exp.GoogleAuthProvider[fn](castObject);
4388
case exp.ProviderId.FACEBOOK:
44-
return exp.FacebookAuthProvider.credentialFromResult(userCredential!);
89+
return exp.FacebookAuthProvider[fn](castObject);
4590
case exp.ProviderId.GITHUB:
46-
return exp.GithubAuthProvider.credentialFromResult(userCredential!);
91+
return exp.GithubAuthProvider[fn](castObject);
4792
case exp.ProviderId.TWITTER:
48-
return exp.TwitterAuthProvider.credentialFromResult(userCredential);
93+
return exp.TwitterAuthProvider[fn](castObject);
4994
default:
5095
const {
5196
oauthIdToken,
@@ -63,21 +108,21 @@ function credentialFromResponse(
63108
return null;
64109
}
65110
// TODO(avolkovi): uncomment this and get it working with SAML & OIDC
66-
// if (pendingToken) {
67-
// if (providerId.indexOf(compat.constants.SAML_PREFIX) == 0) {
68-
// return new impl.SAMLAuthCredential(providerId, pendingToken);
69-
// } else {
70-
// // OIDC and non-default providers excluding Twitter.
71-
// return new impl.OAuthCredential(
72-
// providerId,
73-
// {
74-
// pendingToken,
75-
// idToken: oauthIdToken,
76-
// accessToken: oauthAccessToken
77-
// },
78-
// providerId);
79-
// }
80-
// }
111+
if (pendingToken) {
112+
if (providerId.indexOf('saml.') == 0) {
113+
return exp.SAMLAuthProvider.credential(providerId, pendingToken);
114+
} else {
115+
// OIDC and non-default providers excluding Twitter.
116+
return exp.OAuthCredential._fromParams(
117+
{
118+
providerId,
119+
signInMethod: providerId,
120+
pendingToken,
121+
idToken: oauthIdToken,
122+
accessToken: oauthAccessToken
123+
});
124+
}
125+
}
81126
return new exp.OAuthProvider(providerId).credential({
82127
idToken: oauthIdToken,
83128
accessToken: oauthAccessToken,
@@ -94,12 +139,12 @@ export async function convertCredential(
94139
try {
95140
credential = await credentialPromise;
96141
} catch (e) {
97-
if (e.code === 'auth/multi-factor-auth-required') {
98-
e.resolver = exp.getMultiFactorResolver(auth, e);
142+
if (e instanceof FirebaseError) {
143+
modifyError(auth, e);
99144
}
100145
throw e;
101146
}
102-
const { operationType, user } = await credential;
147+
const { operationType, user } = credential;
103148

104149
return {
105150
operationType,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export { DefaultConfig, AuthImpl, _castAuth } from '../src/core/auth/auth_impl';
3838
export { ClientPlatform, _getClientVersion } from '../src/core/util/version';
3939

4040
export { _generateEventId } from '../src/core/util/event_id';
41-
41+
export { TaggedWithTokenResponse} from '../src/model/id_token';
4242
export { _fail, _assert } from '../src/core/util/assert';
4343
export { AuthPopup } from '../src/platform_browser/util/popup';
4444
export { _getRedirectResult } from '../src/platform_browser/strategies/redirect';

0 commit comments

Comments
 (0)