Skip to content

Commit 004dbb2

Browse files
committed
Add integration tests for changes related to FDL deprecation
1 parent 4e4893a commit 004dbb2

File tree

1 file changed

+162
-1
lines changed

1 file changed

+162
-1
lines changed

test/integration/auth.spec.ts

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
} from '../../lib/auth/index';
3737
import * as sinon from 'sinon';
3838
import * as sinonChai from 'sinon-chai';
39+
import { ActionCodeSettings } from '../../src/auth/action-code-settings-builder';
3940

4041
const chalk = require('chalk'); // eslint-disable-line @typescript-eslint/no-var-requires
4142

@@ -75,10 +76,18 @@ const mockUserData = {
7576
photoURL: 'http://www.example.com/' + newUserUid + '/photo.png',
7677
disabled: false,
7778
};
78-
const actionCodeSettings = {
79+
const actionCodeSettings : ActionCodeSettings = {
7980
url: 'http://localhost/?a=1&b=2#c=3',
8081
handleCodeInApp: false,
8182
};
83+
const actionCodeSettingsWithCustomDomain: ActionCodeSettings = {
84+
url: 'http://localhost/?a=1&b=2#c=3',
85+
handleCodeInApp: true,
86+
linkDomain: 'liubin-dev2.testdomaindonotuse.com',
87+
iOS: {
88+
bundleId: 'com.google.experimental1.dev.extension0',
89+
},
90+
}
8291
let deleteQueue = Promise.resolve();
8392

8493
interface UserImportTest {
@@ -1199,6 +1208,114 @@ describe('admin.auth', () => {
11991208
expect(result.user!.emailVerified).to.be.true;
12001209
});
12011210
});
1211+
1212+
it('generateSignInWithEmailLink() with custom linkDomain should return error in case of invalid hosting domain',
1213+
() => {
1214+
if (authEmulatorHost) {
1215+
return this.skip(); // Not yet supported in Auth Emulator.
1216+
}
1217+
const actionCodeSettingsWithInvalidLinkDomain = deepCopy(actionCodeSettings);
1218+
actionCodeSettingsWithInvalidLinkDomain.linkDomain = 'invaliddomain.firebaseapp.com';
1219+
return getAuth().generateSignInWithEmailLink(email, actionCodeSettingsWithInvalidLinkDomain)
1220+
.catch((error) => {
1221+
expect(error.code).to.equal('auth/invalid-hosting-link-domain');
1222+
});
1223+
});
1224+
1225+
it('generatePasswordResetLink() should return a password reset link with custom domain', () => {
1226+
if (authEmulatorHost) {
1227+
return this.skip(); // Not yet supported in Auth Emulator.
1228+
}
1229+
// Ensure old password set on created user.
1230+
return getAuth().updateUser(uid, { password: 'password' })
1231+
.then(() => {
1232+
return getAuth().generatePasswordResetLink(email, actionCodeSettingsWithCustomDomain);
1233+
})
1234+
.then((link) => {
1235+
const code = getActionCode(link);
1236+
expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettings.url);
1237+
expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain);
1238+
return clientAuth().confirmPasswordReset(code, newPassword);
1239+
})
1240+
.then(() => {
1241+
return clientAuth().signInWithEmailAndPassword(email, newPassword);
1242+
})
1243+
.then((result) => {
1244+
expect(result.user).to.exist;
1245+
expect(result.user!.email).to.equal(email);
1246+
// Password reset also verifies the user's email.
1247+
expect(result.user!.emailVerified).to.be.true;
1248+
});
1249+
});
1250+
1251+
it('generateEmailVerificationLink() should return a verification link with custom domain', () => {
1252+
if (authEmulatorHost) {
1253+
return this.skip(); // Not yet supported in Auth Emulator.
1254+
}
1255+
// Ensure the user's email is unverified.
1256+
return getAuth().updateUser(uid, { password: '123456', emailVerified: false })
1257+
.then((userRecord) => {
1258+
expect(userRecord.emailVerified).to.be.false;
1259+
return getAuth().generateEmailVerificationLink(email, actionCodeSettingsWithCustomDomain);
1260+
})
1261+
.then((link) => {
1262+
const code = getActionCode(link);
1263+
expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettings.url);
1264+
expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain);
1265+
return clientAuth().applyActionCode(code);
1266+
})
1267+
.then(() => {
1268+
return clientAuth().signInWithEmailAndPassword(email, userData.password);
1269+
})
1270+
.then((result) => {
1271+
expect(result.user).to.exist;
1272+
expect(result.user!.email).to.equal(email);
1273+
expect(result.user!.emailVerified).to.be.true;
1274+
});
1275+
});
1276+
1277+
it('generateSignInWithEmailLink() should return a sign-in link with custom domain', () => {
1278+
if (authEmulatorHost) {
1279+
return this.skip(); // Not yet supported in Auth Emulator.
1280+
}
1281+
return getAuth().generateSignInWithEmailLink(email, actionCodeSettingsWithCustomDomain)
1282+
.then((link) => {
1283+
expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettingsWithCustomDomain.url);
1284+
expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain);
1285+
return clientAuth().signInWithEmailLink(email, link);
1286+
})
1287+
.then((result) => {
1288+
expect(result.user).to.exist;
1289+
expect(result.user!.email).to.equal(email);
1290+
expect(result.user!.emailVerified).to.be.true;
1291+
});
1292+
});
1293+
1294+
it('generateVerifyAndChangeEmailLink() should return a verification link with custom domain', function () {
1295+
if (authEmulatorHost) {
1296+
return this.skip(); // Not yet supported in Auth Emulator.
1297+
}
1298+
// Ensure the user's email is verified.
1299+
return getAuth().updateUser(uid, { password: '123456', emailVerified: true })
1300+
.then((userRecord) => {
1301+
expect(userRecord.emailVerified).to.be.true;
1302+
return getAuth().generateVerifyAndChangeEmailLink(email, newEmail, actionCodeSettingsWithCustomDomain);
1303+
})
1304+
.then((link) => {
1305+
const code = getActionCode(link);
1306+
expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettings.url);
1307+
expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain);
1308+
return clientAuth().applyActionCode(code);
1309+
})
1310+
.then(() => {
1311+
return clientAuth().signInWithEmailAndPassword(newEmail, 'password');
1312+
})
1313+
.then((result) => {
1314+
expect(result.user).to.exist;
1315+
expect(result.user!.email).to.equal(newEmail);
1316+
expect(result.user!.emailVerified).to.be.true;
1317+
});
1318+
});
12021319
});
12031320

12041321
describe('Project config management operations', () => {
@@ -1285,6 +1402,9 @@ describe('admin.auth', () => {
12851402
},
12861403
emailPrivacyConfig: {
12871404
enableImprovedEmailPrivacy: true,
1405+
},
1406+
mobileLinksConfig: {
1407+
domain: 'HOSTING_DOMAIN',
12881408
}
12891409
};
12901410
const projectConfigOption2: UpdateProjectConfigRequest = {
@@ -1318,6 +1438,9 @@ describe('admin.auth', () => {
13181438
emailPrivacyConfig: {
13191439
enableImprovedEmailPrivacy: true,
13201440
},
1441+
mobileLinksConfig: {
1442+
domain: 'HOSTING_DOMAIN',
1443+
},
13211444
};
13221445
const expectedProjectConfig2: any = {
13231446
smsRegionConfig: smsRegionAllowlistOnlyConfig,
@@ -1333,6 +1456,9 @@ describe('admin.auth', () => {
13331456
],
13341457
},
13351458
emailPrivacyConfig: {},
1459+
mobileLinksConfig: {
1460+
domain: 'HOSTING_DOMAIN',
1461+
},
13361462
};
13371463
const expectedProjectConfigSmsEnabledTotpDisabled: any = {
13381464
smsRegionConfig: smsRegionAllowlistOnlyConfig,
@@ -1348,6 +1474,9 @@ describe('admin.auth', () => {
13481474
],
13491475
},
13501476
emailPrivacyConfig: {},
1477+
mobileLinksConfig: {
1478+
domain: 'HOSTING_DOMAIN',
1479+
},
13511480
};
13521481

13531482
it('updateProjectConfig() should resolve with the updated project config', () => {
@@ -3194,6 +3323,38 @@ function getContinueUrl(link: string): string {
31943323
return continueUrl!;
31953324
}
31963325

3326+
/**
3327+
* Returns the host name corresponding to the link.
3328+
*
3329+
* @param link The link to parse for hostname
3330+
* @returns Hostname in the link
3331+
*/
3332+
function getHostName(link: string): string {
3333+
const parsedUrl = new url.URL(link);
3334+
return parsedUrl.hostname;
3335+
}
3336+
3337+
/**
3338+
* Returns continue URL for handling in app requests.
3339+
* URL will be of the form, http://abc/__/auth/link?link=<action link url>
3340+
* Coninue URL will be part of action link url
3341+
*
3342+
* @param link
3343+
* @returns
3344+
*/
3345+
function getContinueUrlForInAppRequest(link: string): string {
3346+
// Extract action url from link param
3347+
const parsedUrl = new url.URL(link);
3348+
const linkParam = parsedUrl.searchParams.get('link') ?? '';
3349+
expect(linkParam).is.not.empty;
3350+
3351+
// Extract continueUrl param from action url
3352+
const actionUrl = new url.URL(linkParam);
3353+
const continueUrl = actionUrl.searchParams.get('continueUrl');
3354+
expect(continueUrl).to.exist;
3355+
return continueUrl!;
3356+
}
3357+
31973358
/**
31983359
* Returns the tenant ID corresponding to the link.
31993360
*

0 commit comments

Comments
 (0)