Skip to content

Commit 827ba0e

Browse files
Add beforeEmailSent and beforeSmsSent trigger types (#1621)
* 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 <pragatimodi@google.com>
1 parent 6b02fd3 commit 827ba0e

File tree

7 files changed

+651
-129
lines changed

7 files changed

+651
-129
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add support for beforeSmsSent auth blocking triggers. (#1589)

spec/common/providers/identity.spec.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,8 @@ describe("identity", () => {
528528
userAgent: "USER_AGENT",
529529
eventId: "EVENT_ID",
530530
eventType: EVENT,
531+
emailType: undefined,
532+
smsType: undefined,
531533
authType: "UNAUTHENTICATED",
532534
resource: {
533535
service: "identitytoolkit.googleapis.com",
@@ -540,6 +542,8 @@ describe("identity", () => {
540542
username: undefined,
541543
isNewUser: false,
542544
recaptchaScore: TEST_RECAPTCHA_SCORE,
545+
email: undefined,
546+
phoneNumber: undefined,
543547
},
544548
credential: null,
545549
params: {},
@@ -577,6 +581,8 @@ describe("identity", () => {
577581
userAgent: "USER_AGENT",
578582
eventId: "EVENT_ID",
579583
eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn:password",
584+
emailType: undefined,
585+
smsType: undefined,
580586
authType: "UNAUTHENTICATED",
581587
resource: {
582588
service: "identitytoolkit.googleapis.com",
@@ -589,6 +595,8 @@ describe("identity", () => {
589595
username: undefined,
590596
isNewUser: false,
591597
recaptchaScore: TEST_RECAPTCHA_SCORE,
598+
email: undefined,
599+
phoneNumber: undefined,
592600
},
593601
credential: {
594602
claims: undefined,
@@ -663,6 +671,8 @@ describe("identity", () => {
663671
userAgent: "USER_AGENT",
664672
eventId: "EVENT_ID",
665673
eventType: "providers/cloud.auth/eventTypes/user.beforeCreate:oidc.provider",
674+
emailType: undefined,
675+
smsType: undefined,
666676
authType: "USER",
667677
resource: {
668678
service: "identitytoolkit.googleapis.com",
@@ -675,6 +685,8 @@ describe("identity", () => {
675685
profile: rawUserInfo,
676686
isNewUser: true,
677687
recaptchaScore: TEST_RECAPTCHA_SCORE,
688+
email: undefined,
689+
phoneNumber: undefined,
678690
},
679691
credential: {
680692
claims: undefined,
@@ -691,6 +703,98 @@ describe("identity", () => {
691703

692704
expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
693705
});
706+
707+
it("should parse a beforeSendEmail event", () => {
708+
const time = now.getTime();
709+
const decodedJwt = {
710+
iss: "https://securetoken.google.com/project_id",
711+
aud: "https://us-east1-project_id.cloudfunctions.net/function-1",
712+
iat: 1,
713+
exp: 60 * 60 + 1,
714+
event_id: "EVENT_ID",
715+
event_type: "beforeSendEmail",
716+
user_agent: "USER_AGENT",
717+
ip_address: "1.2.3.4",
718+
locale: "en",
719+
recaptcha_score: TEST_RECAPTCHA_SCORE,
720+
email_type: "RESET_PASSWORD",
721+
email: "johndoe@gmail.com",
722+
};
723+
const context = {
724+
locale: "en",
725+
ipAddress: "1.2.3.4",
726+
userAgent: "USER_AGENT",
727+
eventId: "EVENT_ID",
728+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
729+
emailType: "RESET_PASSWORD",
730+
smsType: undefined,
731+
authType: "UNAUTHENTICATED",
732+
resource: {
733+
service: "identitytoolkit.googleapis.com",
734+
name: "projects/project-id",
735+
},
736+
timestamp: new Date(1000).toUTCString(),
737+
additionalUserInfo: {
738+
isNewUser: false,
739+
profile: undefined,
740+
providerId: undefined,
741+
username: undefined,
742+
recaptchaScore: TEST_RECAPTCHA_SCORE,
743+
email: "johndoe@gmail.com",
744+
phoneNumber: undefined,
745+
},
746+
credential: null,
747+
params: {},
748+
};
749+
750+
expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
751+
});
752+
753+
it("should parse a beforeSendSms event", () => {
754+
const time = now.getTime();
755+
const decodedJwt = {
756+
iss: "https://securetoken.google.com/project_id",
757+
aud: "https://us-east1-project_id.cloudfunctions.net/function-1",
758+
iat: 1,
759+
exp: 60 * 60 + 1,
760+
event_id: "EVENT_ID",
761+
event_type: "beforeSendSms",
762+
user_agent: "USER_AGENT",
763+
ip_address: "1.2.3.4",
764+
locale: "en",
765+
recaptcha_score: TEST_RECAPTCHA_SCORE,
766+
sms_type: "SIGN_IN_OR_SIGN_UP",
767+
phone_number: "+11234567890",
768+
};
769+
const context = {
770+
locale: "en",
771+
ipAddress: "1.2.3.4",
772+
userAgent: "USER_AGENT",
773+
eventId: "EVENT_ID",
774+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
775+
emailType: undefined,
776+
smsType: "SIGN_IN_OR_SIGN_UP",
777+
authType: "UNAUTHENTICATED",
778+
resource: {
779+
service: "identitytoolkit.googleapis.com",
780+
name: "projects/project-id",
781+
},
782+
timestamp: new Date(1000).toUTCString(),
783+
additionalUserInfo: {
784+
isNewUser: false,
785+
profile: undefined,
786+
providerId: undefined,
787+
username: undefined,
788+
recaptchaScore: TEST_RECAPTCHA_SCORE,
789+
email: undefined,
790+
phoneNumber: "+11234567890",
791+
},
792+
credential: null,
793+
params: {},
794+
};
795+
796+
expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
797+
});
694798
});
695799

696800
describe("validateAuthResponse", () => {

spec/v1/providers/auth.spec.ts

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,186 @@ describe("Auth Functions", () => {
305305
});
306306
});
307307

308+
describe("beforeEmail", () => {
309+
it("should create function without options", () => {
310+
const fn = auth.user().beforeEmail(() => Promise.resolve());
311+
312+
expect(fn.__trigger).to.deep.equal({
313+
labels: {},
314+
blockingTrigger: {
315+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
316+
options: {
317+
accessToken: false,
318+
idToken: false,
319+
refreshToken: false,
320+
},
321+
},
322+
});
323+
expect(fn.__endpoint).to.deep.equal({
324+
...MINIMAL_V1_ENDPOINT,
325+
platform: "gcfv1",
326+
labels: {},
327+
blockingTrigger: {
328+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
329+
options: {
330+
accessToken: false,
331+
idToken: false,
332+
refreshToken: false,
333+
},
334+
},
335+
});
336+
expect(fn.__requiredAPIs).to.deep.equal([
337+
{
338+
api: "identitytoolkit.googleapis.com",
339+
reason: "Needed for auth blocking functions",
340+
},
341+
]);
342+
});
343+
344+
it("should create the function with options", () => {
345+
const fn = functions
346+
.region("us-east1")
347+
.runWith({
348+
timeoutSeconds: 90,
349+
memory: "256MB",
350+
})
351+
.auth.user({
352+
blockingOptions: {
353+
accessToken: true,
354+
refreshToken: false,
355+
},
356+
})
357+
.beforeEmail(() => Promise.resolve());
358+
359+
expect(fn.__trigger).to.deep.equal({
360+
labels: {},
361+
regions: ["us-east1"],
362+
availableMemoryMb: 256,
363+
timeout: "90s",
364+
blockingTrigger: {
365+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
366+
options: {
367+
accessToken: true,
368+
idToken: false,
369+
refreshToken: false,
370+
},
371+
},
372+
});
373+
expect(fn.__endpoint).to.deep.equal({
374+
...MINIMAL_V1_ENDPOINT,
375+
platform: "gcfv1",
376+
labels: {},
377+
region: ["us-east1"],
378+
availableMemoryMb: 256,
379+
timeoutSeconds: 90,
380+
blockingTrigger: {
381+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
382+
options: {
383+
accessToken: true,
384+
idToken: false,
385+
refreshToken: false,
386+
},
387+
},
388+
});
389+
expect(fn.__requiredAPIs).to.deep.equal([
390+
{
391+
api: "identitytoolkit.googleapis.com",
392+
reason: "Needed for auth blocking functions",
393+
},
394+
]);
395+
});
396+
});
397+
398+
describe("beforeSms", () => {
399+
it("should create function without options", () => {
400+
const fn = auth.user().beforeSms(() => Promise.resolve());
401+
402+
expect(fn.__trigger).to.deep.equal({
403+
labels: {},
404+
blockingTrigger: {
405+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
406+
options: {
407+
accessToken: false,
408+
idToken: false,
409+
refreshToken: false,
410+
},
411+
},
412+
});
413+
expect(fn.__endpoint).to.deep.equal({
414+
...MINIMAL_V1_ENDPOINT,
415+
platform: "gcfv1",
416+
labels: {},
417+
blockingTrigger: {
418+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
419+
options: {
420+
accessToken: false,
421+
idToken: false,
422+
refreshToken: false,
423+
},
424+
},
425+
});
426+
expect(fn.__requiredAPIs).to.deep.equal([
427+
{
428+
api: "identitytoolkit.googleapis.com",
429+
reason: "Needed for auth blocking functions",
430+
},
431+
]);
432+
});
433+
434+
it("should create the function with options", () => {
435+
const fn = functions
436+
.region("us-east1")
437+
.runWith({
438+
timeoutSeconds: 90,
439+
memory: "256MB",
440+
})
441+
.auth.user({
442+
blockingOptions: {
443+
accessToken: true,
444+
refreshToken: false,
445+
},
446+
})
447+
.beforeSms(() => Promise.resolve());
448+
449+
expect(fn.__trigger).to.deep.equal({
450+
labels: {},
451+
regions: ["us-east1"],
452+
availableMemoryMb: 256,
453+
timeout: "90s",
454+
blockingTrigger: {
455+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
456+
options: {
457+
accessToken: true,
458+
idToken: false,
459+
refreshToken: false,
460+
},
461+
},
462+
});
463+
expect(fn.__endpoint).to.deep.equal({
464+
...MINIMAL_V1_ENDPOINT,
465+
platform: "gcfv1",
466+
labels: {},
467+
region: ["us-east1"],
468+
availableMemoryMb: 256,
469+
timeoutSeconds: 90,
470+
blockingTrigger: {
471+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendSms",
472+
options: {
473+
accessToken: true,
474+
idToken: false,
475+
refreshToken: false,
476+
},
477+
},
478+
});
479+
expect(fn.__requiredAPIs).to.deep.equal([
480+
{
481+
api: "identitytoolkit.googleapis.com",
482+
reason: "Needed for auth blocking functions",
483+
},
484+
]);
485+
});
486+
});
487+
308488
describe("#_dataConstructor", () => {
309489
let cloudFunctionDelete: CloudFunction<UserRecord>;
310490

0 commit comments

Comments
 (0)