Skip to content

Commit b537e21

Browse files
committed
Add linkDomain field to ActionCodeSettings
1 parent f7c6dc4 commit b537e21

File tree

12 files changed

+79
-16
lines changed

12 files changed

+79
-16
lines changed

docs-devsite/auth.actioncodesettings.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface ActionCodeSettings
2626
| [dynamicLinkDomain](./auth.actioncodesettings.md#actioncodesettingsdynamiclinkdomain) | string | When multiple custom dynamic link domains are defined for a project, specify which one to use when the link is to be opened via a specified mobile app (for example, <code>example.page.link</code>). |
2727
| [handleCodeInApp](./auth.actioncodesettings.md#actioncodesettingshandlecodeinapp) | boolean | When set to true, the action code link will be be sent as a Universal Link or Android App Link and will be opened by the app if installed. |
2828
| [iOS](./auth.actioncodesettings.md#actioncodesettingsios) | { bundleId: string; } | Sets the iOS bundle ID. |
29+
| [linkDomain](./auth.actioncodesettings.md#actioncodesettingslinkdomain) | string | The optional custom Firebase Hosting domain to use when the link is to be opened via a specified mobile app. The domain must be configured in Firebase Hosting and owned by the project. This is a replacement of the Dynamic Link. |
2930
| [url](./auth.actioncodesettings.md#actioncodesettingsurl) | string | Sets the link continue/state URL. |
3031

3132
## ActionCodeSettings.android
@@ -82,11 +83,21 @@ iOS?: {
8283
};
8384
```
8485

86+
## ActionCodeSettings.linkDomain
87+
88+
The optional custom Firebase Hosting domain to use when the link is to be opened via a specified mobile app. The domain must be configured in Firebase Hosting and owned by the project. This is a replacement of the Dynamic Link.
89+
90+
<b>Signature:</b>
91+
92+
```typescript
93+
linkDomain?: string;
94+
```
95+
8596
## ActionCodeSettings.url
8697

8798
Sets the link continue/state URL.
8899

89-
This has different meanings in different contexts: - When the link is handled in the web action widgets, this is the deep link in the `continueUrl` query parameter. - When the link is handled in the app directly, this is the `continueUrl` query parameter in the deep link of the Dynamic Link.
100+
This has different meanings in different contexts: - When the link is handled in the web action widgets, this is the deep link in the `continueUrl` query parameter. - When the link is handled in the app directly, this is the `continueUrl` query parameter in the deep link of the Dynamic Link or Hosting Link.
90101

91102
<b>Signature:</b>
92103

docs-devsite/auth.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,7 @@ AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY: {
19541954
readonly MISSING_RECAPTCHA_VERSION: "auth/missing-recaptcha-version";
19551955
readonly INVALID_RECAPTCHA_VERSION: "auth/invalid-recaptcha-version";
19561956
readonly INVALID_REQ_TYPE: "auth/invalid-req-type";
1957+
readonly INVALID_HOSTING_LINK_DOMAIN: "auth/invalid-hosting-link-domain";
19571958
}
19581959
```
19591960

packages/auth-types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export type ActionCodeSettings = {
130130
iOS?: { bundleId: string };
131131
url: string;
132132
dynamicLinkDomain?: string;
133+
linkDomain?: string;
133134
};
134135

135136
export type AdditionalUserInfo = {

packages/auth/src/api/authentication/email_and_password.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export interface GetOobCodeRequest {
7070
dynamicLinkDomain?: string;
7171
tenantId?: string;
7272
targetProjectid?: string;
73+
linkDomain?: string;
7374
}
7475

7576
export interface VerifyEmailRequest extends GetOobCodeRequest {

packages/auth/src/api/errors.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ export const enum ServerError {
100100
MISSING_RECAPTCHA_VERSION = 'MISSING_RECAPTCHA_VERSION',
101101
INVALID_RECAPTCHA_VERSION = 'INVALID_RECAPTCHA_VERSION',
102102
INVALID_REQ_TYPE = 'INVALID_REQ_TYPE',
103-
PASSWORD_DOES_NOT_MEET_REQUIREMENTS = 'PASSWORD_DOES_NOT_MEET_REQUIREMENTS'
103+
PASSWORD_DOES_NOT_MEET_REQUIREMENTS = 'PASSWORD_DOES_NOT_MEET_REQUIREMENTS',
104+
INVALID_HOSTING_LINK_DOMAIN = 'INVALID_HOSTING_LINK_DOMAIN'
104105
}
105106

106107
/**

packages/auth/src/core/errors.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ export const enum AuthErrorCode {
134134
INVALID_RECAPTCHA_VERSION = 'invalid-recaptcha-version',
135135
INVALID_REQ_TYPE = 'invalid-req-type',
136136
UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION = 'unsupported-password-policy-schema-version',
137-
PASSWORD_DOES_NOT_MEET_REQUIREMENTS = 'password-does-not-meet-requirements'
137+
PASSWORD_DOES_NOT_MEET_REQUIREMENTS = 'password-does-not-meet-requirements',
138+
INVALID_HOSTING_LINK_DOMAIN = 'invalid-hosting-link-domain'
138139
}
139140

140141
function _debugErrorMap(): ErrorMap<AuthErrorCode> {
@@ -387,7 +388,9 @@ function _debugErrorMap(): ErrorMap<AuthErrorCode> {
387388
[AuthErrorCode.UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION]:
388389
'The password policy received from the backend uses a schema version that is not supported by this version of the Firebase SDK.',
389390
[AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS]:
390-
'The password does not meet the requirements.'
391+
'The password does not meet the requirements.',
392+
[AuthErrorCode.INVALID_HOSTING_LINK_DOMAIN]:
393+
'The provided hosting link domain is not configured in Firebase Hosting or is not owned by the current project.'
391394
};
392395
}
393396

@@ -598,5 +601,6 @@ export const AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY = {
598601
MISSING_CLIENT_TYPE: 'auth/missing-client-type',
599602
MISSING_RECAPTCHA_VERSION: 'auth/missing-recaptcha-version',
600603
INVALID_RECAPTCHA_VERSION: 'auth/invalid-recaptcha-version',
601-
INVALID_REQ_TYPE: 'auth/invalid-req-type'
604+
INVALID_REQ_TYPE: 'auth/invalid-req-type',
605+
INVALID_HOSTING_LINK_DOMAIN: 'auth/invalid-hosting-link-domain'
602606
} as const;

packages/auth/src/core/strategies/action_code_settings.test.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('core/strategies/action_code_settings', () => {
4848
_setActionCodeSettingsOnRequest(auth, request, {
4949
handleCodeInApp: true,
5050
iOS: {
51-
bundleId: 'my-´bundle'
51+
bundleId: 'my-bundle'
5252
},
5353
url: 'my-url'
5454
})
@@ -60,14 +60,27 @@ describe('core/strategies/action_code_settings', () => {
6060
_setActionCodeSettingsOnRequest(auth, request, {
6161
handleCodeInApp: true,
6262
iOS: {
63-
bundleId: 'my-´bundle'
63+
bundleId: 'my-bundle'
6464
},
6565
url: 'my-url',
6666
dynamicLinkDomain: ''
6767
})
6868
).to.throw(FirebaseError, '(auth/invalid-dynamic-link-domain)');
6969
});
7070

71+
it('should require a non empty hosting link URL', () => {
72+
expect(() =>
73+
_setActionCodeSettingsOnRequest(auth, request, {
74+
handleCodeInApp: true,
75+
iOS: {
76+
bundleId: 'my-bundle'
77+
},
78+
url: 'my-url',
79+
linkDomain: ''
80+
})
81+
).to.throw(FirebaseError, '(auth/invalid-hosting-link-domain)');
82+
});
83+
7184
it('should require a non-empty bundle ID', () => {
7285
expect(() =>
7386
_setActionCodeSettingsOnRequest(auth, request, {

packages/auth/src/core/strategies/action_code_settings.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,16 @@ export function _setActionCodeSettingsOnRequest(
3737
auth,
3838
AuthErrorCode.INVALID_DYNAMIC_LINK_DOMAIN
3939
);
40+
_assert(
41+
typeof actionCodeSettings.linkDomain === 'undefined' ||
42+
actionCodeSettings.linkDomain.length > 0,
43+
auth,
44+
AuthErrorCode.INVALID_HOSTING_LINK_DOMAIN
45+
);
4046

4147
request.continueUrl = actionCodeSettings.url;
4248
request.dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain;
49+
request.linkDomain = actionCodeSettings.linkDomain;
4350
request.canHandleCodeInApp = actionCodeSettings.handleCodeInApp;
4451

4552
if (actionCodeSettings.iOS) {

packages/auth/src/core/strategies/email.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,16 @@ describe('core/strategies/sendEmailVerification', () => {
162162
bundleId: 'my-bundle'
163163
},
164164
url: 'my-url',
165-
dynamicLinkDomain: 'fdl-domain'
165+
dynamicLinkDomain: 'fdl-domain',
166+
linkDomain: 'hosting-link-domain'
166167
});
167168

168169
expect(mock.calls[0].request).to.eql({
169170
requestType: ActionCodeOperation.VERIFY_EMAIL,
170171
idToken,
171172
continueUrl: 'my-url',
172173
dynamicLinkDomain: 'fdl-domain',
174+
linkDomain: 'hosting-link-domain',
173175
canHandleCodeInApp: true,
174176
iOSBundleId: 'my-bundle'
175177
});
@@ -190,13 +192,15 @@ describe('core/strategies/sendEmailVerification', () => {
190192
packageName: 'my-package'
191193
},
192194
url: 'my-url',
193-
dynamicLinkDomain: 'fdl-domain'
195+
dynamicLinkDomain: 'fdl-domain',
196+
linkDomain: 'hosting-link-domain'
194197
});
195198
expect(mock.calls[0].request).to.eql({
196199
requestType: ActionCodeOperation.VERIFY_EMAIL,
197200
idToken,
198201
continueUrl: 'my-url',
199202
dynamicLinkDomain: 'fdl-domain',
203+
linkDomain: 'hosting-link-domain',
200204
canHandleCodeInApp: true,
201205
androidInstallApp: false,
202206
androidMinimumVersionCode: 'my-version',
@@ -270,7 +274,8 @@ describe('core/strategies/verifyBeforeUpdateEmail', () => {
270274
bundleId: 'my-bundle'
271275
},
272276
url: 'my-url',
273-
dynamicLinkDomain: 'fdl-domain'
277+
dynamicLinkDomain: 'fdl-domain',
278+
linkDomain: 'hosting-link-domain'
274279
});
275280

276281
expect(mock.calls[0].request).to.eql({
@@ -279,6 +284,7 @@ describe('core/strategies/verifyBeforeUpdateEmail', () => {
279284
newEmail,
280285
continueUrl: 'my-url',
281286
dynamicLinkDomain: 'fdl-domain',
287+
linkDomain: 'hosting-link-domain',
282288
canHandleCodeInApp: true,
283289
iOSBundleId: 'my-bundle'
284290
});
@@ -299,14 +305,16 @@ describe('core/strategies/verifyBeforeUpdateEmail', () => {
299305
packageName: 'my-package'
300306
},
301307
url: 'my-url',
302-
dynamicLinkDomain: 'fdl-domain'
308+
dynamicLinkDomain: 'fdl-domain',
309+
linkDomain: 'hosting-link-domain'
303310
});
304311
expect(mock.calls[0].request).to.eql({
305312
requestType: ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL,
306313
idToken,
307314
newEmail,
308315
continueUrl: 'my-url',
309316
dynamicLinkDomain: 'fdl-domain',
317+
linkDomain: 'hosting-link-domain',
310318
canHandleCodeInApp: true,
311319
androidInstallApp: false,
312320
androidMinimumVersionCode: 'my-version',

packages/auth/src/core/strategies/email_and_password.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,16 @@ describe('core/strategies/sendPasswordResetEmail', () => {
120120
bundleId: 'my-bundle'
121121
},
122122
url: 'my-url',
123-
dynamicLinkDomain: 'fdl-domain'
123+
dynamicLinkDomain: 'fdl-domain',
124+
linkDomain: 'hosting-link-domain'
124125
});
125126

126127
expect(mock.calls[0].request).to.eql({
127128
requestType: ActionCodeOperation.PASSWORD_RESET,
128129
email,
129130
continueUrl: 'my-url',
130131
dynamicLinkDomain: 'fdl-domain',
132+
linkDomain: 'hosting-link-domain',
131133
canHandleCodeInApp: true,
132134
iOSBundleId: 'my-bundle',
133135
clientType: 'CLIENT_TYPE_WEB'
@@ -148,13 +150,15 @@ describe('core/strategies/sendPasswordResetEmail', () => {
148150
packageName: 'my-package'
149151
},
150152
url: 'my-url',
151-
dynamicLinkDomain: 'fdl-domain'
153+
dynamicLinkDomain: 'fdl-domain',
154+
linkDomain: 'hosting-link-domain'
152155
});
153156
expect(mock.calls[0].request).to.eql({
154157
requestType: ActionCodeOperation.PASSWORD_RESET,
155158
email,
156159
continueUrl: 'my-url',
157160
dynamicLinkDomain: 'fdl-domain',
161+
linkDomain: 'hosting-link-domain',
158162
canHandleCodeInApp: true,
159163
androidInstallApp: false,
160164
androidMinimumVersionCode: 'my-version',

packages/auth/src/core/strategies/email_link.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,16 @@ describe('core/strategies/sendSignInLinkToEmail', () => {
123123
bundleId: 'my-bundle'
124124
},
125125
url: 'my-url',
126-
dynamicLinkDomain: 'fdl-domain'
126+
dynamicLinkDomain: 'fdl-domain',
127+
linkDomain: 'hosting-link-domain'
127128
});
128129

129130
expect(mock.calls[0].request).to.eql({
130131
requestType: ActionCodeOperation.EMAIL_SIGNIN,
131132
email,
132133
continueUrl: 'my-url',
133134
dynamicLinkDomain: 'fdl-domain',
135+
linkDomain: 'hosting-link-domain',
134136
canHandleCodeInApp: true,
135137
iOSBundleId: 'my-bundle',
136138
clientType: 'CLIENT_TYPE_WEB'
@@ -151,13 +153,15 @@ describe('core/strategies/sendSignInLinkToEmail', () => {
151153
packageName: 'my-package'
152154
},
153155
url: 'my-url',
154-
dynamicLinkDomain: 'fdl-domain'
156+
dynamicLinkDomain: 'fdl-domain',
157+
linkDomain: 'hosting-link-domain'
155158
});
156159
expect(mock.calls[0].request).to.eql({
157160
requestType: ActionCodeOperation.EMAIL_SIGNIN,
158161
email,
159162
continueUrl: 'my-url',
160163
dynamicLinkDomain: 'fdl-domain',
164+
linkDomain: 'hosting-link-domain',
161165
canHandleCodeInApp: true,
162166
androidInstallApp: false,
163167
androidMinimumVersionCode: 'my-version',

packages/auth/src/model/public_types.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ export interface ActionCodeSettings {
504504
* - When the link is handled in the web action widgets, this is the deep link in the
505505
* `continueUrl` query parameter.
506506
* - When the link is handled in the app directly, this is the `continueUrl` query parameter in
507-
* the deep link of the Dynamic Link.
507+
* the deep link of the Dynamic Link or Hosting Link.
508508
*/
509509
url: string;
510510
/**
@@ -515,6 +515,14 @@ export interface ActionCodeSettings {
515515
* @defaultValue The first domain is automatically selected.
516516
*/
517517
dynamicLinkDomain?: string;
518+
/**
519+
* The optional custom Firebase Hosting domain to use when the link is to be opened via
520+
* a specified mobile app. The domain must be configured in Firebase Hosting and owned
521+
* by the project.
522+
* This is a replacement of the Dynamic Link.
523+
* @defaultValue The default hosting domain will be used (for example, `example.firebaseapp.com`)
524+
*/
525+
linkDomain?: string;
518526
}
519527

520528
/**

0 commit comments

Comments
 (0)