Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update actionCodeSetting with linkDomain field #2676

Open
wants to merge 1 commit into
base: fdl-deprecation
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions etc/firebase-admin.auth.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ export interface ActionCodeSettings {
installApp?: boolean;
minimumVersion?: string;
};
// @deprecated
dynamicLinkDomain?: string;
handleCodeInApp?: boolean;
iOS?: {
bundleId: string;
};
linkDomain?: string;
url: string;
}

Expand Down Expand Up @@ -223,6 +225,11 @@ export class AuthClientErrorCode {
message: string;
};
// (undocumented)
static INVALID_HOSTING_LINK_DOMAIN: {
code: string;
message: string;
};
// (undocumented)
static INVALID_ID_TOKEN: {
code: string;
message: string;
Expand Down
22 changes: 22 additions & 0 deletions src/auth/action-code-settings-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,27 @@ export interface ActionCodeSettings {
* configured per project. This field provides the ability to explicitly choose
* configured per project. This fields provides the ability explicitly choose
* one. If none is provided, the oldest domain is used by default.
* @deprecated use linkDomain instead
*/
dynamicLinkDomain?: string;

/**
* Defines the custom Firebase Hosting domain to use when the link is to be opened
* via a specified mobile app,
* This is a replacement of Firebase Dynamic Link.
* If none is provided,
* a default hosting domain will be used (for example, `example.firebaseapp.com`)
*/

linkDomain?: string;
}

/** Defines the email action code server request. */
interface EmailActionCodeRequest {
continueUrl?: string;
canHandleCodeInApp?: boolean;
dynamicLinkDomain?: string;
linkDomain?: string;
androidPackageName?: string;
androidMinimumVersion: string;
androidInstallApp?: boolean;
Expand All @@ -123,6 +135,7 @@ export class ActionCodeSettingsBuilder {
private ibi?: string;
private canHandleCodeInApp?: boolean;
private dynamicLinkDomain?: string;
private linkDomain?: string;

/**
* ActionCodeSettingsBuilder constructor.
Expand Down Expand Up @@ -166,6 +179,14 @@ export class ActionCodeSettingsBuilder {
}
this.dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain;

if (typeof actionCodeSettings.linkDomain !== 'undefined' &&
!validator.isNonEmptyString(actionCodeSettings.linkDomain)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_HOSTING_LINK_DOMAIN,
);
}
this.linkDomain = actionCodeSettings.linkDomain;

if (typeof actionCodeSettings.iOS !== 'undefined') {
if (!validator.isNonNullObject(actionCodeSettings.iOS)) {
throw new FirebaseAuthError(
Expand Down Expand Up @@ -230,6 +251,7 @@ export class ActionCodeSettingsBuilder {
continueUrl: this.continueUrl,
canHandleCodeInApp: this.canHandleCodeInApp,
dynamicLinkDomain: this.dynamicLinkDomain,
linkDomain: this.linkDomain,
androidPackageName: this.apn,
androidMinimumVersion: this.amv,
androidInstallApp: this.installApp,
Expand Down
6 changes: 3 additions & 3 deletions src/auth/base-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ export abstract class BaseAuth {
* minimumVersion: '12'
* },
* handleCodeInApp: true,
* dynamicLinkDomain: 'custom.page.link'
* linkDomain: 'project-id.firebaseapp.com'
* };
* admin.auth()
* .generatePasswordResetLink('user@example.com', actionCodeSettings)
Expand Down Expand Up @@ -802,7 +802,7 @@ export abstract class BaseAuth {
* minimumVersion: '12'
* },
* handleCodeInApp: true,
* dynamicLinkDomain: 'custom.page.link'
* linkDomain: 'project-id.firebaseapp.com'
* };
* admin.auth()
* .generateEmailVerificationLink('user@example.com', actionCodeSettings)
Expand Down Expand Up @@ -883,7 +883,7 @@ export abstract class BaseAuth {
* minimumVersion: '12'
* },
* handleCodeInApp: true,
* dynamicLinkDomain: 'custom.page.link'
* linkDomain: 'project-id.firebaseapp.com'
* };
* admin.auth()
* .generateEmailVerificationLink('user@example.com', actionCodeSettings)
Expand Down
7 changes: 7 additions & 0 deletions src/utils/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ export class AuthClientErrorCode {
message: 'The provided dynamic link domain is not configured or authorized ' +
'for the current project.',
};
public static INVALID_HOSTING_LINK_DOMAIN = {
code: 'invalid-hosting-link-domain',
message: 'The provided hosting link domain is not configured in Firebase ' +
'Hosting or is not owned by the current project.',
};
public static INVALID_EMAIL_VERIFIED = {
code: 'invalid-email-verified',
message: 'The emailVerified field must be a boolean.',
Expand Down Expand Up @@ -933,6 +938,8 @@ const AUTH_SERVER_TO_CLIENT_CODE: ServerToClientCode = {
INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI',
// Dynamic link domain in provided ActionCodeSettings is not authorized.
INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN',
// Hosting link domain in provided ActionCodeSettings is not owned by the current project.
INVALID_HOSTING_LINK_DOMAIN: 'INVALID_HOSTING_LINK_DOMAIN',
// uploadAccount provides an email that already exists.
DUPLICATE_EMAIL: 'EMAIL_ALREADY_EXISTS',
// uploadAccount provides a localId that already exists.
Expand Down
21 changes: 21 additions & 0 deletions test/unit/auth/action-code-settings-builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ chai.use(sinonChai);
chai.use(chaiAsPromised);

const expect = chai.expect;
const TEST_LINK_DOMAIN = 'project-id.firebaseapp.com';

describe('ActionCodeSettingsBuilder', () => {
describe('constructor', () => {
Expand All @@ -43,7 +44,10 @@ describe('ActionCodeSettingsBuilder', () => {
installApp: true,
minimumVersion: '6',
},
// not removing this test since we are going to accept both dynamicLinkDomain
// and linkDomain for the onboarding phase.
dynamicLinkDomain: 'custom.page.link',
linkDomain: TEST_LINK_DOMAIN,
})).not.to.throw;
});

Expand All @@ -69,6 +73,7 @@ describe('ActionCodeSettingsBuilder', () => {
minimumVersion: '6',
},
dynamicLinkDomain: 'custom.page.link',
linkDomain: TEST_LINK_DOMAIN,
} as any);
}).to.throw(AuthClientErrorCode.MISSING_CONTINUE_URI.message);
});
Expand Down Expand Up @@ -109,6 +114,20 @@ describe('ActionCodeSettingsBuilder', () => {
});
});

const invalidHostingDomains = [null, NaN, 0, 1, true, false, '',
[TEST_LINK_DOMAIN], [], {}, { a: 1 }, _.noop];
invalidHostingDomains.forEach((domain) => {
it('should throw on invalid linkDomain:' + JSON.stringify(domain), () => {
expect(() => {
return new ActionCodeSettingsBuilder({
url: 'https://www.example.com/path/file?a=1&b=2',
handleCodeInApp: true,
linkDomain: domain,
} as any);
}).to.throw(AuthClientErrorCode.INVALID_HOSTING_LINK_DOMAIN.message);
});
});

const invalidIOSSettings = [null, NaN, 0, 1, true, false, '', 'a', [], [1, 'a'], _.noop];
invalidIOSSettings.forEach((settings) => {
it('should throw on invalid iOS object:' + JSON.stringify(settings), () => {
Expand Down Expand Up @@ -228,11 +247,13 @@ describe('ActionCodeSettingsBuilder', () => {
minimumVersion: '6',
},
dynamicLinkDomain: 'custom.page.link',
linkDomain: TEST_LINK_DOMAIN,
});
const expectedRequest = {
continueUrl: 'https://www.example.com/path/file?a=1&b=2',
canHandleCodeInApp: true,
dynamicLinkDomain: 'custom.page.link',
linkDomain: TEST_LINK_DOMAIN,
androidPackageName: 'com.example.android',
androidMinimumVersion: '6',
androidInstallApp: true,
Expand Down
1 change: 1 addition & 0 deletions test/unit/auth/auth-api-request.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3078,6 +3078,7 @@ AUTH_REQUEST_HANDLER_TESTS.forEach((handler) => {
minimumVersion: '6',
},
dynamicLinkDomain: 'custom.page.link',
linkDomain: 'project-id.firebaseapp.com',
};
const expectedActionCodeSettingsRequest = new ActionCodeSettingsBuilder(actionCodeSettings).buildRequest();
const expectedLink = 'https://custom.page.link?link=' +
Expand Down
1 change: 1 addition & 0 deletions test/unit/auth/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2887,6 +2887,7 @@ AUTH_CONFIGS.forEach((testConfig) => {
minimumVersion: '6',
},
dynamicLinkDomain: 'custom.page.link',
linkDomain: 'project-id.firebaseapp.com',
};
const expectedLink = 'https://custom.page.link?link=' +
encodeURIComponent('https://projectId.firebaseapp.com/__/auth/action?oobCode=CODE') +
Expand Down