Skip to content

Commit fd8bd0c

Browse files
committed
Responded to reviewer comments.
1 parent e911a96 commit fd8bd0c

File tree

4 files changed

+124
-62
lines changed

4 files changed

+124
-62
lines changed

packages-exp/auth-exp/src/core/user/additional_user_info.test.ts

Lines changed: 85 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,101 +16,148 @@
1616
*/
1717

1818
import { expect } from 'chai';
19-
import { IdTokenResponse } from '../../model/id_token';
20-
import { ProviderId } from '../providers';
2119
import { fromIdTokenResponse } from './additional_user_info';
20+
import { IdTokenResponse, IdTokenResponseKind } from '../../model/id_token';
21+
import { ProviderId } from '../providers';
22+
import { UserProfile } from '../../model/user';
2223

2324
describe('core/user/additional_user_info', () => {
24-
2525
describe('fromIdTokenResponse', () => {
26-
const profile = {login: 'scott', friends: [], netWorth: 5.00};
27-
const rawUserInfo = JSON.stringify(profile);
26+
const userProfileWithLogin: UserProfile = {
27+
login: 'scott',
28+
friends: [],
29+
netWorth: 5.0
30+
};
31+
const rawUserInfoWithLogin = JSON.stringify(userProfileWithLogin);
32+
const userProfileNoLogin: UserProfile = { sample: 'data' };
33+
const rawUserInfoNoLogin = JSON.stringify(userProfileNoLogin);
2834

2935
describe('parses federated IDP response tokens', () => {
30-
3136
it('for FacebookAdditionalUserInfo', () => {
32-
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({providerId: ProviderId.FACEBOOK, rawUserInfo}))!;
33-
const {isNewUser, providerId, username, profile} = additionalUserInfo;
37+
const idResponse = idTokenResponse({
38+
providerId: ProviderId.FACEBOOK,
39+
rawUserInfo: rawUserInfoWithLogin
40+
});
41+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
42+
const { isNewUser, providerId, username, profile } = additionalUserInfo;
3443
expect(isNewUser).to.be.false;
3544
expect(providerId).to.eq(ProviderId.FACEBOOK);
3645
expect(username).to.be.null;
37-
expect(profile).to.eq(profile);
46+
expect(profile).to.eq(userProfileWithLogin);
3847
});
3948

4049
it('for GithubAdditionalUserInfo', () => {
41-
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({providerId: ProviderId.GITHUB, rawUserInfo}))!;
42-
const {isNewUser, providerId, username, profile} = additionalUserInfo;
50+
const idResponse = idTokenResponse({
51+
providerId: ProviderId.GITHUB,
52+
rawUserInfo: rawUserInfoWithLogin
53+
});
54+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
55+
const { isNewUser, providerId, username, profile } = additionalUserInfo;
4356
expect(isNewUser).to.be.false;
4457
expect(providerId).to.eq(ProviderId.GITHUB);
4558
expect(username).to.eq('scott');
46-
expect(profile).to.eq(profile);
59+
expect(profile).to.eq(userProfileWithLogin);
4760
});
4861

4962
it('for GoogleAdditionalUserInfo', () => {
50-
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({providerId: ProviderId.GOOGLE, rawUserInfo}))!;
51-
const {isNewUser, providerId, username, profile} = additionalUserInfo;
63+
const idResponse = idTokenResponse({
64+
providerId: ProviderId.GOOGLE,
65+
rawUserInfo: rawUserInfoWithLogin
66+
});
67+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
68+
const { isNewUser, providerId, username, profile } = additionalUserInfo;
5269
expect(isNewUser).to.be.false;
5370
expect(providerId).to.eq(ProviderId.GOOGLE);
5471
expect(username).to.be.null;
55-
expect(profile).to.eq(profile);
72+
expect(profile).to.eq(userProfileWithLogin);
5673
});
5774

5875
it('for TwitterAdditionalUserInfo', () => {
59-
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({providerId: ProviderId.TWITTER, rawUserInfo, screenName: 'scott'}))!;
60-
const {isNewUser, providerId, username, profile} = additionalUserInfo;
76+
const idResponse = idTokenResponse({
77+
providerId: ProviderId.TWITTER,
78+
rawUserInfo: rawUserInfoNoLogin,
79+
screenName: 'scott'
80+
});
81+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
82+
const { isNewUser, providerId, username, profile } = additionalUserInfo;
6183
expect(isNewUser).to.be.false;
6284
expect(providerId).to.eq(ProviderId.TWITTER);
6385
expect(username).to.eq('scott');
64-
expect(profile).to.eq(profile);
86+
expect(profile).to.eql(userProfileNoLogin);
6587
});
6688
});
6789

6890
describe('parses profile data', () => {
69-
7091
it('for valid JSON', () => {
71-
expect(fromIdTokenResponse(idTokenResponse({providerId: ProviderId.FACEBOOK, rawUserInfo}))!.profile).to.deep.eq(profile);
92+
const idResponse = idTokenResponse({
93+
providerId: ProviderId.FACEBOOK,
94+
rawUserInfo: rawUserInfoWithLogin
95+
});
96+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
97+
expect(additionalUserInfo.profile).to.eql(userProfileWithLogin);
7298
});
7399

74100
it('for missing JSON', () => {
75-
expect(fromIdTokenResponse(idTokenResponse({providerId: ProviderId.FACEBOOK}))!.profile).to.deep.eq({});
101+
const idResponse = idTokenResponse({ providerId: ProviderId.FACEBOOK });
102+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
103+
expect(additionalUserInfo.profile).to.be.empty;
76104
});
77105
});
78106

79107
describe('determines new-user status', () => {
80-
81108
it('for new users by token response', () => {
82-
expect(fromIdTokenResponse(idTokenResponse({providerId: ProviderId.FACEBOOK, isNewUser: true}))!.isNewUser).to.be.true;
109+
const idResponse = idTokenResponse({
110+
providerId: ProviderId.FACEBOOK,
111+
isNewUser: true
112+
});
113+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
114+
expect(additionalUserInfo.isNewUser).to.be.true;
83115
});
84116

85117
it('for new users by toolkit response kind', () => {
86-
expect(fromIdTokenResponse(idTokenResponse({providerId: ProviderId.FACEBOOK, kind: 'identitytoolkit#SignupNewUserResponse'}))!.isNewUser).to.be.true;
118+
const idResponse = idTokenResponse({
119+
providerId: ProviderId.FACEBOOK,
120+
kind: IdTokenResponseKind.SignupNewUser
121+
});
122+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
123+
expect(additionalUserInfo.isNewUser).to.be.true;
87124
});
88125

89126
it('for old users', () => {
90-
expect(fromIdTokenResponse(idTokenResponse({providerId: ProviderId.FACEBOOK}))!.isNewUser).to.be.false;
127+
const idResponse = idTokenResponse({ providerId: ProviderId.FACEBOOK });
128+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
129+
expect(additionalUserInfo.isNewUser).to.be.false;
91130
});
92131
});
93132

94133
describe('creates generic AdditionalUserInfo', () => {
95-
96134
it('for custom auth', () => {
97-
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({providerId: ProviderId.CUSTOM, rawUserInfo}))!;
98-
const {isNewUser, providerId, username, profile} = additionalUserInfo;
135+
const idResponse = idTokenResponse({
136+
providerId: ProviderId.CUSTOM,
137+
rawUserInfo: rawUserInfoWithLogin
138+
});
139+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
140+
const { isNewUser, providerId, username, profile } = additionalUserInfo;
99141
expect(isNewUser).to.be.false;
100142
expect(providerId).to.be.null;
101143
expect(username).to.be.null;
102144
expect(profile).to.eq(profile);
103145
});
104146

105147
it('for anonymous auth', () => {
106-
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({providerId: ProviderId.ANONYMOUS, rawUserInfo}))!;
107-
const {isNewUser, providerId, username, profile} = additionalUserInfo;
148+
const idResponse = idTokenResponse({
149+
providerId: ProviderId.ANONYMOUS,
150+
rawUserInfo: rawUserInfoWithLogin
151+
});
152+
const additionalUserInfo = fromIdTokenResponse(idResponse)!;
153+
const { isNewUser, providerId, username, profile } = additionalUserInfo;
108154
expect(isNewUser).to.be.false;
109155
expect(providerId).to.be.null;
110156
expect(username).to.be.null;
111157
expect(profile).to.eq(profile);
112158
});
113159
/*
160+
Uncomment this once ID token parsing is built
114161
it('for missing provider IDs in response but not in token', () => {
115162
const additionalUserInfo = fromIdTokenResponse(idTokenResponse({rawUserInfo}))!;
116163
const {isNewUser, providerId, username, profile} = additionalUserInfo;
@@ -124,29 +171,21 @@ describe('core/user/additional_user_info', () => {
124171

125172
describe('returns null', () => {
126173
it('for missing provider IDs', () => {
127-
expect(fromIdTokenResponse(idTokenResponse({}))).to.be.null;
174+
const idResponse = idTokenResponse({});
175+
const additionalUserInfo = fromIdTokenResponse(idResponse);
176+
expect(additionalUserInfo).to.be.null;
128177
});
129178
});
130179
});
131180
});
132181

133-
function idTokenResponse(partial: PartialIdTokenResponse): IdTokenResponse {
182+
function idTokenResponse(partial: Partial<IdTokenResponse>): IdTokenResponse {
134183
return {
135184
idToken: 'Parsing logic not implemented',
136-
refreshToken: 'Doesn\'t matter',
137-
expiresIn: 'Doesn\'t matter',
138-
localId: 'Doesn\'t matter',
139-
kind: 'Not a new user response ',
185+
refreshToken: "Doesn't matter",
186+
expiresIn: "Doesn't matter",
187+
localId: "Doesn't matter",
188+
kind: IdTokenResponseKind.CreateAuthUri,
140189
...partial
141190
};
142191
}
143-
144-
interface PartialIdTokenResponse {
145-
providerId?: ProviderId;
146-
isNewUser?: boolean;
147-
rawUserInfo?: string;
148-
screenName?: string | null;
149-
displayName?: string | null;
150-
photoUrl?: string | null;
151-
kind?: string;
152-
}

packages-exp/auth-exp/src/core/user/additional_user_info.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
import { IdTokenResponse } from '../../model/id_token';
17+
import { AdditionalUserInfo, UserProfile } from '../../model/user';
18+
import { IdTokenResponse, IdTokenResponseKind } from '../../model/id_token';
1819
import { ProviderId } from '../providers';
19-
import { AdditionalUserInfo } from '../../model/user';
2020

2121
export function fromIdTokenResponse(
2222
idTokenResponse: IdTokenResponse
@@ -28,8 +28,9 @@ export function fromIdTokenResponse(
2828
: {};
2929
const isNewUser =
3030
!!idTokenResponse.isNewUser ||
31-
idTokenResponse.kind === 'identitytoolkit#SignupNewUserResponse';
31+
idTokenResponse.kind === IdTokenResponseKind.SignupNewUser;
3232
/*
33+
Uncomment this once ID token parsing is built
3334
if (!providerId && !!idTokenResponse) {
3435
const providerId = parseIdToken(idTokenResponse.idToken).signInProvider;
3536
return new GenericAdditionalUserInfo(isNewUser, providerId, null, profile);
@@ -69,18 +70,18 @@ class GenericAdditionalUserInfo implements AdditionalUserInfo {
6970
readonly isNewUser: boolean,
7071
readonly providerId: ProviderId | null,
7172
readonly username: string | null,
72-
readonly profile: { [key: string]: unknown } | null
73+
readonly profile: UserProfile
7374
) {}
7475
}
7576

7677
class FacebookAdditionalUserInfo extends GenericAdditionalUserInfo {
77-
constructor(isNewUser: boolean, profile: { [key: string]: unknown } | null) {
78+
constructor(isNewUser: boolean, profile: UserProfile) {
7879
super(isNewUser, ProviderId.FACEBOOK, null, profile);
7980
}
8081
}
8182

8283
class GithubAdditionalUserInfo extends GenericAdditionalUserInfo {
83-
constructor(isNewUser: boolean, profile: { [key: string]: unknown } | null) {
84+
constructor(isNewUser: boolean, profile: UserProfile) {
8485
super(
8586
isNewUser,
8687
ProviderId.GITHUB,
@@ -91,15 +92,15 @@ class GithubAdditionalUserInfo extends GenericAdditionalUserInfo {
9192
}
9293

9394
class GoogleAdditionalUserInfo extends GenericAdditionalUserInfo {
94-
constructor(isNewUser: boolean, profile: { [key: string]: unknown } | null) {
95+
constructor(isNewUser: boolean, profile: UserProfile) {
9596
super(isNewUser, ProviderId.GOOGLE, null, profile);
9697
}
9798
}
9899

99100
class TwitterAdditionalUserInfo extends GenericAdditionalUserInfo {
100101
constructor(
101102
isNewUser: boolean,
102-
profile: { [key: string]: unknown } | null,
103+
profile: UserProfile,
103104
screenName: string | null
104105
) {
105106
super(isNewUser, ProviderId.TWITTER, screenName, profile);

packages-exp/auth-exp/src/model/id_token.d.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,43 @@ export interface ParsedIdToken {
4646
* IdToken as returned by the API
4747
*/
4848
export interface IdTokenResponse {
49-
providerId?: ProviderId;
50-
idToken: IdToken;
51-
refreshToken: string;
5249
expiresIn: string;
50+
idToken: IdToken;
5351
localId: string;
52+
providerId?: ProviderId;
53+
refreshToken: string;
5454

5555
// MFA-specific fields
56-
mfaPendingCredential?: string;
5756
mfaInfo?: APIMFAInfo[];
57+
mfaPendingCredential?: string;
5858

5959
// Used in AdditionalUserInfo
60+
displayName?: string | null;
6061
isNewUser?: boolean;
62+
kind: IdTokenResponseKind;
63+
photoUrl?: string | null;
6164
rawUserInfo?: string;
6265
screenName?: string | null;
63-
displayName?: string | null;
64-
photoUrl?: string | null;
65-
kind: string;
66+
}
67+
68+
/**
69+
* The possible types of the `IdTokenResponse`
70+
*/
71+
export enum IdTokenResponseKind {
72+
CreateAuthUri = 'identitytoolkit#CreateAuthUriResponse',
73+
DeleteAccount = 'identitytoolkit#DeleteAccountResponse',
74+
DownloadAccount = 'identitytoolkit#DownloadAccountResponse',
75+
EmailLinkSignin = 'identitytoolkit#EmailLinkSigninResponse',
76+
GetAccountInfo = 'identitytoolkit#GetAccountInfoResponse',
77+
GetOobConfirmationCode = 'identitytoolkit#GetOobConfirmationCodeResponse',
78+
GetRecaptchaParam = 'identitytoolkit#GetRecaptchaParamResponse',
79+
ResetPassword = 'identitytoolkit#ResetPasswordResponse',
80+
SetAccountInfo = 'identitytoolkit#SetAccountInfoResponse',
81+
SignupNewUser = 'identitytoolkit#SignupNewUserResponse',
82+
UploadAccount = 'identitytoolkit#UploadAccountResponse',
83+
VerifyAssertion = 'identitytoolkit#VerifyAssertionResponse',
84+
VerifyCustomToken = 'identitytoolkit#VerifyCustomTokenResponse',
85+
VerifyPassword = 'identitytoolkit#VerifyPasswordResponse'
6686
}
6787

6888
/**

packages-exp/auth-exp/src/model/user.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ import { ProviderId } from '../core/providers';
2020
import { Auth } from './auth';
2121
import { IdTokenResult } from './id_token';
2222

23+
export type UserProfile = { [key: string]: unknown } | null;
24+
2325
export interface AdditionalUserInfo {
2426
readonly isNewUser: boolean;
25-
readonly profile: { [key: string]: unknown } | null;
27+
readonly profile: UserProfile;
2628
readonly providerId: ProviderId | null;
2729
readonly username: string | null;
2830
}

0 commit comments

Comments
 (0)