Skip to content

Commit

Permalink
Add beforeEmailSent and beforeSmsSent trigger types (#1621)
Browse files Browse the repository at this point in the history
* add support for beforeEmail trigger

* remove opts from beforeemail & decode user record only for beforeCreate and beforeSignIn

* fix unit tests

* add changelog

* add comment to authblockingevent type

* rebase

* rebase

* Add beforeSmsSent blocking functions trigger

* adding spec.ts changes

* lint

* rebase

* rebase

* changelog

* remove duplicate unit test

* update EmailType to EMAIL_SIGN_IN | PASSWORD_RESET

* api comment fixes

* minor docstring fix

---------

Co-authored-by: Pragati <[email protected]>
  • Loading branch information
blidd-google and pragatimodi authored Oct 21, 2024
1 parent 6b02fd3 commit 827ba0e
Show file tree
Hide file tree
Showing 7 changed files with 651 additions and 129 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add support for beforeSmsSent auth blocking triggers. (#1589)
104 changes: 104 additions & 0 deletions spec/common/providers/identity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,8 @@ describe("identity", () => {
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: EVENT,
emailType: undefined,
smsType: undefined,
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
Expand All @@ -540,6 +542,8 @@ describe("identity", () => {
username: undefined,
isNewUser: false,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
phoneNumber: undefined,
},
credential: null,
params: {},
Expand Down Expand Up @@ -577,6 +581,8 @@ describe("identity", () => {
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn:password",
emailType: undefined,
smsType: undefined,
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
Expand All @@ -589,6 +595,8 @@ describe("identity", () => {
username: undefined,
isNewUser: false,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
phoneNumber: undefined,
},
credential: {
claims: undefined,
Expand Down Expand Up @@ -663,6 +671,8 @@ describe("identity", () => {
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeCreate:oidc.provider",
emailType: undefined,
smsType: undefined,
authType: "USER",
resource: {
service: "identitytoolkit.googleapis.com",
Expand All @@ -675,6 +685,8 @@ describe("identity", () => {
profile: rawUserInfo,
isNewUser: true,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
phoneNumber: undefined,
},
credential: {
claims: undefined,
Expand All @@ -691,6 +703,98 @@ describe("identity", () => {

expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
});

it("should parse a beforeSendEmail event", () => {
const time = now.getTime();
const decodedJwt = {
iss: "https://securetoken.google.com/project_id",
aud: "https://us-east1-project_id.cloudfunctions.net/function-1",
iat: 1,
exp: 60 * 60 + 1,
event_id: "EVENT_ID",
event_type: "beforeSendEmail",
user_agent: "USER_AGENT",
ip_address: "1.2.3.4",
locale: "en",
recaptcha_score: TEST_RECAPTCHA_SCORE,
email_type: "RESET_PASSWORD",
email: "[email protected]",
};
const context = {
locale: "en",
ipAddress: "1.2.3.4",
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
emailType: "RESET_PASSWORD",
smsType: undefined,
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
name: "projects/project-id",
},
timestamp: new Date(1000).toUTCString(),
additionalUserInfo: {
isNewUser: false,
profile: undefined,
providerId: undefined,
username: undefined,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: "[email protected]",
phoneNumber: undefined,
},
credential: null,
params: {},
};

expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
});

it("should parse a beforeSendSms event", () => {
const time = now.getTime();
const decodedJwt = {
iss: "https://securetoken.google.com/project_id",
aud: "https://us-east1-project_id.cloudfunctions.net/function-1",
iat: 1,
exp: 60 * 60 + 1,
event_id: "EVENT_ID",
event_type: "beforeSendSms",
user_agent: "USER_AGENT",
ip_address: "1.2.3.4",
locale: "en",
recaptcha_score: TEST_RECAPTCHA_SCORE,
sms_type: "SIGN_IN_OR_SIGN_UP",
phone_number: "+11234567890",
};
const context = {
locale: "en",
ipAddress: "1.2.3.4",
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
emailType: undefined,
smsType: "SIGN_IN_OR_SIGN_UP",
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
name: "projects/project-id",
},
timestamp: new Date(1000).toUTCString(),
additionalUserInfo: {
isNewUser: false,
profile: undefined,
providerId: undefined,
username: undefined,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
phoneNumber: "+11234567890",
},
credential: null,
params: {},
};

expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
});
});

describe("validateAuthResponse", () => {
Expand Down
180 changes: 180 additions & 0 deletions spec/v1/providers/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,186 @@ describe("Auth Functions", () => {
});
});

describe("beforeEmail", () => {
it("should create function without options", () => {
const fn = auth.user().beforeEmail(() => Promise.resolve());

expect(fn.__trigger).to.deep.equal({
labels: {},
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: false,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V1_ENDPOINT,
platform: "gcfv1",
labels: {},
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: false,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__requiredAPIs).to.deep.equal([
{
api: "identitytoolkit.googleapis.com",
reason: "Needed for auth blocking functions",
},
]);
});

it("should create the function with options", () => {
const fn = functions
.region("us-east1")
.runWith({
timeoutSeconds: 90,
memory: "256MB",
})
.auth.user({
blockingOptions: {
accessToken: true,
refreshToken: false,
},
})
.beforeEmail(() => Promise.resolve());

expect(fn.__trigger).to.deep.equal({
labels: {},
regions: ["us-east1"],
availableMemoryMb: 256,
timeout: "90s",
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: true,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V1_ENDPOINT,
platform: "gcfv1",
labels: {},
region: ["us-east1"],
availableMemoryMb: 256,
timeoutSeconds: 90,
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: true,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__requiredAPIs).to.deep.equal([
{
api: "identitytoolkit.googleapis.com",
reason: "Needed for auth blocking functions",
},
]);
});
});

describe("beforeSms", () => {
it("should create function without options", () => {
const fn = auth.user().beforeSms(() => Promise.resolve());

expect(fn.__trigger).to.deep.equal({
labels: {},
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
options: {
accessToken: false,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V1_ENDPOINT,
platform: "gcfv1",
labels: {},
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
options: {
accessToken: false,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__requiredAPIs).to.deep.equal([
{
api: "identitytoolkit.googleapis.com",
reason: "Needed for auth blocking functions",
},
]);
});

it("should create the function with options", () => {
const fn = functions
.region("us-east1")
.runWith({
timeoutSeconds: 90,
memory: "256MB",
})
.auth.user({
blockingOptions: {
accessToken: true,
refreshToken: false,
},
})
.beforeSms(() => Promise.resolve());

expect(fn.__trigger).to.deep.equal({
labels: {},
regions: ["us-east1"],
availableMemoryMb: 256,
timeout: "90s",
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
options: {
accessToken: true,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V1_ENDPOINT,
platform: "gcfv1",
labels: {},
region: ["us-east1"],
availableMemoryMb: 256,
timeoutSeconds: 90,
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
options: {
accessToken: true,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__requiredAPIs).to.deep.equal([
{
api: "identitytoolkit.googleapis.com",
reason: "Needed for auth blocking functions",
},
]);
});
});

describe("#_dataConstructor", () => {
let cloudFunctionDelete: CloudFunction<UserRecord>;

Expand Down
Loading

0 comments on commit 827ba0e

Please sign in to comment.