Skip to content

Commit 1baf7d6

Browse files
authored
added ability to custom FDL domain (#1382)
1 parent 97cc3f8 commit 1baf7d6

File tree

9 files changed

+140
-12
lines changed

9 files changed

+140
-12
lines changed

packages/auth-types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export type ActionCodeSettings = {
8888
handleCodeInApp?: boolean;
8989
iOS?: { bundleId: string };
9090
url: string;
91+
dynamicLinkDomain?: string;
9192
};
9293

9394
export type AdditionalUserInfo = {

packages/auth/src/actioncodesettings.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fireauth.ActionCodeSettings.prototype.initialize_ = function(settingsObj) {
5252
(typeof continueUrl === 'string' && !continueUrl.length)) {
5353
throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_CONTINUE_URI);
5454
}
55-
/** @private {string} The continue URL. */
55+
/** @const @private {string} The continue URL. */
5656
this.continueUrl_ = /** @type {string} */ (continueUrl);
5757

5858
// Validate Android parameters.
@@ -140,8 +140,23 @@ fireauth.ActionCodeSettings.prototype.initialize_ = function(settingsObj) {
140140
fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP +
141141
' property must be a boolean when specified.');
142142
}
143-
/** @private {boolean} Whether the code can be handled in app. */
143+
/** @const @private {boolean} Whether the code can be handled in app. */
144144
this.canHandleCodeInApp_ = !!canHandleCodeInApp;
145+
146+
// Validate dynamicLinkDomain.
147+
var dynamicLinkDomain = settingsObj[
148+
fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN];
149+
if (typeof dynamicLinkDomain !== 'undefined' &&
150+
(typeof dynamicLinkDomain !== 'string' ||
151+
(typeof dynamicLinkDomain === 'string' &&
152+
!dynamicLinkDomain.length))) {
153+
throw new fireauth.AuthError(
154+
fireauth.authenum.Error.ARGUMENT_ERROR,
155+
fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN +
156+
' property must be a non empty string when specified.');
157+
}
158+
/** @const @private {?string} The FDL domain. */
159+
this.dynamicLinkDomain_ = dynamicLinkDomain || null;
145160
};
146161

147162

@@ -155,6 +170,7 @@ fireauth.ActionCodeSettings.RequestField = {
155170
ANDROID_PACKAGE_NAME: 'androidPackageName',
156171
CAN_HANDLE_CODE_IN_APP: 'canHandleCodeInApp',
157172
CONTINUE_URL: 'continueUrl',
173+
DYNAMIC_LINK_DOMAIN: 'dynamicLinkDomain',
158174
IOS_BUNDLE_ID: 'iOSBundleId'
159175
};
160176

@@ -165,6 +181,7 @@ fireauth.ActionCodeSettings.RequestField = {
165181
*/
166182
fireauth.ActionCodeSettings.RawField = {
167183
ANDROID: 'android',
184+
DYNAMIC_LINK_DOMAIN: 'dynamicLinkDomain',
168185
HANDLE_CODE_IN_APP: 'handleCodeInApp',
169186
IOS: 'iOS',
170187
URL: 'url'
@@ -212,6 +229,8 @@ fireauth.ActionCodeSettings.prototype.buildRequest = function() {
212229
this.installApp_;
213230
}
214231
request[fireauth.ActionCodeSettings.RequestField.IOS_BUNDLE_ID] = this.ibi_;
232+
request[fireauth.ActionCodeSettings.RequestField.DYNAMIC_LINK_DOMAIN] =
233+
this.dynamicLinkDomain_;
215234
// Remove null fields.
216235
for (var key in request) {
217236
if (request[key] === null) {

packages/auth/src/error_auth.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ fireauth.authenum.Error = {
137137
INVALID_CONTINUE_URI: 'invalid-continue-uri',
138138
INVALID_CORDOVA_CONFIGURATION: 'invalid-cordova-configuration',
139139
INVALID_CUSTOM_TOKEN: 'invalid-custom-token',
140+
INVALID_DYNAMIC_LINK_DOMAIN: 'invalid-dynamic-link-domain',
140141
INVALID_EMAIL: 'invalid-email',
141142
INVALID_IDP_RESPONSE: 'invalid-credential',
142143
INVALID_MESSAGE_PAYLOAD: 'invalid-message-payload',
@@ -262,6 +263,10 @@ fireauth.AuthError.MESSAGES_[
262263
'cordova-plugin-customurlscheme.';
263264
fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CUSTOM_TOKEN] =
264265
'The custom token format is incorrect. Please check the documentation.';
266+
fireauth.AuthError.MESSAGES_[
267+
fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN] = 'The provided ' +
268+
'dynamic link domain is not configured or authorized for the current ' +
269+
'project.';
265270
fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_EMAIL] =
266271
'The email address is badly formatted.';
267272
fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_API_KEY] =

packages/auth/src/rpchandler.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ fireauth.RpcHandler.ServerError = {
198198
INVALID_CODE: 'INVALID_CODE',
199199
INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI',
200200
INVALID_CUSTOM_TOKEN: 'INVALID_CUSTOM_TOKEN',
201+
INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN',
201202
INVALID_EMAIL: 'INVALID_EMAIL',
202203
INVALID_ID_TOKEN: 'INVALID_ID_TOKEN',
203204
INVALID_IDP_RESPONSE: 'INVALID_IDP_RESPONSE',
@@ -2321,6 +2322,8 @@ fireauth.RpcHandler.getDeveloperError_ =
23212322
fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID;
23222323
errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] =
23232324
fireauth.authenum.Error.UNAUTHORIZED_DOMAIN;
2325+
errorMap[fireauth.RpcHandler.ServerError.INVALID_DYNAMIC_LINK_DOMAIN] =
2326+
fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN;
23242327

23252328
// getProjectConfig errors when clientId is passed.
23262329
errorMap[fireauth.RpcHandler.ServerError.INVALID_OAUTH_CLIENT_ID] =

packages/auth/test/actioncodesettings_test.js

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,17 @@ function testActionCodeSettings_success_allParameters() {
5151
'installApp': true,
5252
'minimumVersion': '12'
5353
},
54-
'handleCodeInApp': true
54+
'handleCodeInApp': true,
55+
'dynamicLinkDomain': 'example.page.link'
5556
};
5657
var expectedRequest = {
5758
'continueUrl': 'https://www.example.com/?state=abc',
5859
'iOSBundleId': 'com.example.ios',
5960
'androidPackageName': 'com.example.android',
6061
'androidInstallApp': true,
6162
'androidMinimumVersion': '12',
62-
'canHandleCodeInApp': true
63+
'canHandleCodeInApp': true,
64+
'dynamicLinkDomain': 'example.page.link'
6365
};
6466
var actionCodeSettings = new fireauth.ActionCodeSettings(settings);
6567
assertObjectEquals(expectedRequest, actionCodeSettings.buildRequest());
@@ -82,6 +84,24 @@ function testActionCodeSettings_success_partialParameters() {
8284
}
8385

8486

87+
function testActionCodeSettings_success_partialParameters_fdlDomain() {
88+
var settings = {
89+
'url': 'https://www.example.com/?state=abc',
90+
// Will be ignored.
91+
'iOS': {},
92+
'android': {},
93+
'dynamicLinkDomain': 'example.page.link'
94+
};
95+
var expectedRequest = {
96+
'continueUrl': 'https://www.example.com/?state=abc',
97+
'canHandleCodeInApp': false,
98+
'dynamicLinkDomain': 'example.page.link'
99+
};
100+
var actionCodeSettings = new fireauth.ActionCodeSettings(settings);
101+
assertObjectEquals(expectedRequest, actionCodeSettings.buildRequest());
102+
}
103+
104+
85105
function testActionCodeSettings_success_partialParameters_android() {
86106
var settings = {
87107
'url': 'https://www.example.com/?state=abc',
@@ -100,6 +120,26 @@ function testActionCodeSettings_success_partialParameters_android() {
100120
}
101121

102122

123+
function testActionCodeSettings_success_partialParameters_android_fdlDomain() {
124+
var settings = {
125+
'url': 'https://www.example.com/?state=abc',
126+
'android': {
127+
'packageName': 'com.example.android'
128+
},
129+
'dynamicLinkDomain': 'example.page.link'
130+
};
131+
var expectedRequest = {
132+
'continueUrl': 'https://www.example.com/?state=abc',
133+
'androidPackageName': 'com.example.android',
134+
'androidInstallApp': false,
135+
'canHandleCodeInApp': false,
136+
'dynamicLinkDomain': 'example.page.link'
137+
};
138+
var actionCodeSettings = new fireauth.ActionCodeSettings(settings);
139+
assertObjectEquals(expectedRequest, actionCodeSettings.buildRequest());
140+
}
141+
142+
103143
function testActionCodeSettings_success_partialParameters_ios() {
104144
var settings = {
105145
'url': 'https://www.example.com/?state=abc',
@@ -117,6 +157,25 @@ function testActionCodeSettings_success_partialParameters_ios() {
117157
}
118158

119159

160+
function testActionCodeSettings_success_partialParameters_ios_fdlDomain() {
161+
var settings = {
162+
'url': 'https://www.example.com/?state=abc',
163+
'iOS': {
164+
'bundleId': 'com.example.ios'
165+
},
166+
'dynamicLinkDomain': 'example.page.link'
167+
};
168+
var expectedRequest = {
169+
'continueUrl': 'https://www.example.com/?state=abc',
170+
'iOSBundleId': 'com.example.ios',
171+
'canHandleCodeInApp': false,
172+
'dynamicLinkDomain': 'example.page.link'
173+
};
174+
var actionCodeSettings = new fireauth.ActionCodeSettings(settings);
175+
assertObjectEquals(expectedRequest, actionCodeSettings.buildRequest());
176+
}
177+
178+
120179
function testActionCodeSettings_error_continueUrl() {
121180
// Missing continue URL.
122181
assertActionCodeSettingsErrorThrown(
@@ -258,3 +317,29 @@ function testActionCodeSettings_error_ios() {
258317
},
259318
'auth/argument-error');
260319
}
320+
321+
322+
function testActionCodeSettings_error_dynamicLinkDomain() {
323+
// Invalid dynamic link domain.
324+
assertActionCodeSettingsErrorThrown(
325+
{
326+
'url': 'https://www.example.com/?state=abc',
327+
'dynamicLinkDomain': ['example.page.link']
328+
329+
},
330+
'auth/argument-error');
331+
// Dynamic link domain set to empty string.
332+
assertActionCodeSettingsErrorThrown(
333+
{
334+
'url': 'https://www.example.com/?state=abc',
335+
'dynamicLinkDomain': ''
336+
},
337+
'auth/argument-error');
338+
// Dynamic link domain set to null.
339+
assertActionCodeSettingsErrorThrown(
340+
{
341+
'url': 'https://www.example.com/?state=abc',
342+
'dynamicLinkDomain': null
343+
},
344+
'auth/argument-error');
345+
}

packages/auth/test/auth_test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ var actionCodeSettings = {
148148
'installApp': true,
149149
'minimumVersion': '12'
150150
},
151-
'handleCodeInApp': true
151+
'handleCodeInApp': true,
152+
'dynamicLinkDomain': 'example.page.link'
152153
};
153154
var mockLocalStorage;
154155
var mockSessionStorage;

packages/auth/test/authuser_test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ var actionCodeSettings = {
171171
'installApp': true,
172172
'minimumVersion': '12'
173173
},
174-
'handleCodeInApp': true
174+
'handleCodeInApp': true,
175+
'dynamicLinkDomain': 'example.page.link'
175176
};
176177
var lastLoginAt = '1506050282000';
177178
var createdAt = '1506044998000';

packages/auth/test/rpchandler_test.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,7 +3660,8 @@ function testSendSignInLinkToEmail_success_actionCodeSettings() {
36603660
'androidPackageName': 'com.example.android',
36613661
'androidInstallApp': true,
36623662
'androidMinimumVersion': '12',
3663-
'canHandleCodeInApp': true
3663+
'canHandleCodeInApp': true,
3664+
'dynamicLinkDomain': 'example.page.link'
36643665
};
36653666
var expectedResponse = {'email': userEmail};
36663667
asyncTestCase.waitForSignals(1);
@@ -3676,7 +3677,8 @@ function testSendSignInLinkToEmail_success_actionCodeSettings() {
36763677
'androidPackageName': 'com.example.android',
36773678
'androidInstallApp': true,
36783679
'androidMinimumVersion': '12',
3679-
'canHandleCodeInApp': true
3680+
'canHandleCodeInApp': true,
3681+
'dynamicLinkDomain': 'example.page.link'
36803682
}),
36813683
fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_,
36823684
delay,
@@ -3825,6 +3827,8 @@ function testSendSignInLinkToEmail_serverCaughtError() {
38253827
fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID;
38263828
errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] =
38273829
fireauth.authenum.Error.UNAUTHORIZED_DOMAIN;
3830+
errorMap[fireauth.RpcHandler.ServerError.INVALID_DYNAMIC_LINK_DOMAIN] =
3831+
fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN;
38283832

38293833
assertServerErrorsAreHandled(function() {
38303834
return rpcHandler.sendSignInLinkToEmail(userEmail, {});
@@ -3843,7 +3847,8 @@ function testSendPasswordResetEmail_success_actionCodeSettings() {
38433847
'androidPackageName': 'com.example.android',
38443848
'androidInstallApp': true,
38453849
'androidMinimumVersion': '12',
3846-
'canHandleCodeInApp': true
3850+
'canHandleCodeInApp': true,
3851+
'dynamicLinkDomain': 'example.page.link'
38473852
};
38483853
var expectedResponse = {
38493854
'email': userEmail
@@ -3861,7 +3866,8 @@ function testSendPasswordResetEmail_success_actionCodeSettings() {
38613866
'androidPackageName': 'com.example.android',
38623867
'androidInstallApp': true,
38633868
'androidMinimumVersion': '12',
3864-
'canHandleCodeInApp': true
3869+
'canHandleCodeInApp': true,
3870+
'dynamicLinkDomain': 'example.page.link'
38653871
}),
38663872
fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_,
38673873
delay,
@@ -4012,6 +4018,8 @@ function testSendPasswordResetEmail_caughtServerError() {
40124018
fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID;
40134019
errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] =
40144020
fireauth.authenum.Error.UNAUTHORIZED_DOMAIN;
4021+
errorMap[fireauth.RpcHandler.ServerError.INVALID_DYNAMIC_LINK_DOMAIN] =
4022+
fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN;
40154023

40164024
assertServerErrorsAreHandled(function() {
40174025
return rpcHandler.sendPasswordResetEmail(userEmail, {});
@@ -4034,7 +4042,8 @@ function testSendEmailVerification_success_actionCodeSettings() {
40344042
'androidPackageName': 'com.example.android',
40354043
'androidInstallApp': true,
40364044
'androidMinimumVersion': '12',
4037-
'canHandleCodeInApp': true
4045+
'canHandleCodeInApp': true,
4046+
'dynamicLinkDomain': 'example.page.link'
40384047
};
40394048
asyncTestCase.waitForSignals(1);
40404049
assertSendXhrAndRunCallback(
@@ -4049,7 +4058,8 @@ function testSendEmailVerification_success_actionCodeSettings() {
40494058
'androidPackageName': 'com.example.android',
40504059
'androidInstallApp': true,
40514060
'androidMinimumVersion': '12',
4052-
'canHandleCodeInApp': true
4061+
'canHandleCodeInApp': true,
4062+
'dynamicLinkDomain': 'example.page.link'
40534063
}),
40544064
fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_,
40554065
delay,
@@ -4176,6 +4186,8 @@ function testSendEmailVerification_caughtServerError() {
41764186
fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID;
41774187
errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] =
41784188
fireauth.authenum.Error.UNAUTHORIZED_DOMAIN;
4189+
errorMap[fireauth.RpcHandler.ServerError.INVALID_DYNAMIC_LINK_DOMAIN] =
4190+
fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN;
41794191

41804192
assertServerErrorsAreHandled(function() {
41814193
return rpcHandler.sendEmailVerification(idToken, {});

packages/firebase/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ declare namespace firebase.auth {
190190
handleCodeInApp?: boolean;
191191
iOS?: { bundleId: string };
192192
url: string;
193+
dynamicLinkDomain?: string;
193194
};
194195

195196
type AdditionalUserInfo = {

0 commit comments

Comments
 (0)