Skip to content

Commit 44e4b92

Browse files
committed
add support for beforeEmail trigger
1 parent 414ff0a commit 44e4b92

File tree

6 files changed

+346
-101
lines changed

6 files changed

+346
-101
lines changed

spec/common/providers/identity.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ describe("identity", () => {
528528
userAgent: "USER_AGENT",
529529
eventId: "EVENT_ID",
530530
eventType: EVENT,
531+
emailType: undefined,
531532
authType: "UNAUTHENTICATED",
532533
resource: {
533534
service: "identitytoolkit.googleapis.com",
@@ -540,6 +541,7 @@ describe("identity", () => {
540541
username: undefined,
541542
isNewUser: false,
542543
recaptchaScore: TEST_RECAPTCHA_SCORE,
544+
email: undefined,
543545
},
544546
credential: null,
545547
params: {},
@@ -577,6 +579,7 @@ describe("identity", () => {
577579
userAgent: "USER_AGENT",
578580
eventId: "EVENT_ID",
579581
eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn:password",
582+
emailType: undefined,
580583
authType: "UNAUTHENTICATED",
581584
resource: {
582585
service: "identitytoolkit.googleapis.com",
@@ -589,6 +592,7 @@ describe("identity", () => {
589592
username: undefined,
590593
isNewUser: false,
591594
recaptchaScore: TEST_RECAPTCHA_SCORE,
595+
email: undefined,
592596
},
593597
credential: {
594598
claims: undefined,
@@ -663,6 +667,7 @@ describe("identity", () => {
663667
userAgent: "USER_AGENT",
664668
eventId: "EVENT_ID",
665669
eventType: "providers/cloud.auth/eventTypes/user.beforeCreate:oidc.provider",
670+
emailType: undefined,
666671
authType: "USER",
667672
resource: {
668673
service: "identitytoolkit.googleapis.com",
@@ -675,6 +680,7 @@ describe("identity", () => {
675680
profile: rawUserInfo,
676681
isNewUser: true,
677682
recaptchaScore: TEST_RECAPTCHA_SCORE,
683+
email: undefined,
678684
},
679685
credential: {
680686
claims: undefined,
@@ -691,6 +697,50 @@ describe("identity", () => {
691697

692698
expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
693699
});
700+
701+
it("should parse a beforeSendEmail event", () => {
702+
const time = now.getTime();
703+
const decodedJwt = {
704+
iss: "https://securetoken.google.com/project_id",
705+
aud: "https://us-east1-project_id.cloudfunctions.net/function-1",
706+
iat: 1,
707+
exp: 60 * 60 + 1,
708+
event_id: "EVENT_ID",
709+
event_type: "beforeSendEmail",
710+
user_agent: "USER_AGENT",
711+
ip_address: "1.2.3.4",
712+
locale: "en",
713+
recaptcha_score: TEST_RECAPTCHA_SCORE,
714+
email_type: "RESET_PASSWORD",
715+
716+
};
717+
const context = {
718+
locale: "en",
719+
ipAddress: "1.2.3.4",
720+
userAgent: "USER_AGENT",
721+
eventId: "EVENT_ID",
722+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
723+
emailType: "RESET_PASSWORD",
724+
authType: "UNAUTHENTICATED",
725+
resource: {
726+
service: "identitytoolkit.googleapis.com",
727+
name: "projects/project-id",
728+
},
729+
timestamp: new Date(1000).toUTCString(),
730+
additionalUserInfo: {
731+
isNewUser: false,
732+
profile: undefined,
733+
providerId: undefined,
734+
username: undefined,
735+
recaptchaScore: TEST_RECAPTCHA_SCORE,
736+
737+
},
738+
credential: null,
739+
params: {},
740+
};
741+
742+
expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
743+
});
694744
});
695745

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

spec/v1/providers/auth.spec.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,96 @@ 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+
308398
describe("#_dataConstructor", () => {
309399
let cloudFunctionDelete: CloudFunction<UserRecord>;
310400

spec/v2/providers/identity.spec.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ const BEFORE_SIGN_IN_TRIGGER = {
4141
},
4242
};
4343

44+
const BEFORE_EMAIL_TRIGGER = {
45+
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
46+
options: {
47+
accessToken: false,
48+
idToken: false,
49+
refreshToken: false,
50+
},
51+
};
52+
4453
const opts: identity.BlockingOptions = {
4554
accessToken: true,
4655
refreshToken: false,
@@ -137,6 +146,50 @@ describe("identity", () => {
137146
});
138147
});
139148

149+
describe("beforeEmailSent", () => {
150+
it("should accept a handler", () => {
151+
const fn = identity.beforeEmailSent(() => Promise.resolve());
152+
153+
expect(fn.__endpoint).to.deep.equal({
154+
...MINIMAL_V2_ENDPOINT,
155+
platform: "gcfv2",
156+
labels: {},
157+
blockingTrigger: BEFORE_EMAIL_TRIGGER,
158+
});
159+
expect(fn.__requiredAPIs).to.deep.equal([
160+
{
161+
api: "identitytoolkit.googleapis.com",
162+
reason: "Needed for auth blocking functions",
163+
},
164+
]);
165+
});
166+
});
167+
168+
it("should accept options and a handler", () => {
169+
const fn = identity.beforeEmailSent(opts, () => Promise.resolve());
170+
171+
expect(fn.__endpoint).to.deep.equal({
172+
...MINIMAL_V2_ENDPOINT,
173+
platform: "gcfv2",
174+
labels: {},
175+
minInstances: 1,
176+
region: ["us-west1"],
177+
blockingTrigger: {
178+
...BEFORE_EMAIL_TRIGGER,
179+
options: {
180+
...BEFORE_EMAIL_TRIGGER.options,
181+
accessToken: true,
182+
},
183+
},
184+
});
185+
expect(fn.__requiredAPIs).to.deep.equal([
186+
{
187+
api: "identitytoolkit.googleapis.com",
188+
reason: "Needed for auth blocking functions",
189+
},
190+
]);
191+
});
192+
140193
describe("beforeOperation", () => {
141194
it("should handle eventType and handler for before create events", () => {
142195
const fn = identity.beforeOperation("beforeCreate", () => Promise.resolve(), undefined);
@@ -172,6 +225,23 @@ describe("identity", () => {
172225
]);
173226
});
174227

228+
it("should handle eventType and handler for before email events", () => {
229+
const fn = identity.beforeOperation("beforeSendEmail", () => Promise.resolve(), undefined);
230+
231+
expect(fn.__endpoint).to.deep.equal({
232+
...MINIMAL_V2_ENDPOINT,
233+
platform: "gcfv2",
234+
labels: {},
235+
blockingTrigger: BEFORE_EMAIL_TRIGGER,
236+
});
237+
expect(fn.__requiredAPIs).to.deep.equal([
238+
{
239+
api: "identitytoolkit.googleapis.com",
240+
reason: "Needed for auth blocking functions",
241+
},
242+
]);
243+
});
244+
175245
it("should handle eventType, options, and handler for before create events", () => {
176246
const fn = identity.beforeOperation("beforeCreate", opts, () => Promise.resolve());
177247

@@ -221,6 +291,31 @@ describe("identity", () => {
221291
},
222292
]);
223293
});
294+
295+
it("should handle eventType, options, and handler for before send email events", () => {
296+
const fn = identity.beforeOperation("beforeSendEmail", opts, () => Promise.resolve());
297+
298+
expect(fn.__endpoint).to.deep.equal({
299+
...MINIMAL_V2_ENDPOINT,
300+
platform: "gcfv2",
301+
labels: {},
302+
minInstances: 1,
303+
region: ["us-west1"],
304+
blockingTrigger: {
305+
...BEFORE_EMAIL_TRIGGER,
306+
options: {
307+
...BEFORE_EMAIL_TRIGGER.options,
308+
accessToken: true,
309+
},
310+
},
311+
});
312+
expect(fn.__requiredAPIs).to.deep.equal([
313+
{
314+
api: "identitytoolkit.googleapis.com",
315+
reason: "Needed for auth blocking functions",
316+
},
317+
]);
318+
});
224319
});
225320

226321
describe("getOpts", () => {

0 commit comments

Comments
 (0)