firebase-functions 6.0.1 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -85,6 +85,14 @@ export interface CallableRequest<T = any> {
85
85
  */
86
86
  rawRequest: Request;
87
87
  }
88
+ /**
89
+ * CallableProxyResponse exposes subset of express.Response object
90
+ * to allow writing partial, streaming responses back to the client.
91
+ */
92
+ export interface CallableProxyResponse {
93
+ write: express.Response["write"];
94
+ acceptsStreaming: boolean;
95
+ }
88
96
  /**
89
97
  * The set of Firebase Functions status codes. The codes are the same at the
90
98
  * ones exposed by {@link https://github.com/grpc/grpc/blob/master/doc/statuscodes.md | gRPC}.
@@ -385,8 +385,8 @@ async function checkAppCheckToken(req, ctx, options) {
385
385
  }
386
386
  }
387
387
  /** @internal */
388
- function onCallHandler(options, handler) {
389
- const wrapped = wrapOnCallHandler(options, handler);
388
+ function onCallHandler(options, handler, version) {
389
+ const wrapped = wrapOnCallHandler(options, handler, version);
390
390
  return (req, res) => {
391
391
  return new Promise((resolve) => {
392
392
  res.on("finish", resolve);
@@ -397,8 +397,11 @@ function onCallHandler(options, handler) {
397
397
  };
398
398
  }
399
399
  exports.onCallHandler = onCallHandler;
400
+ function encodeSSE(data) {
401
+ return `data: ${JSON.stringify(data)}\n`;
402
+ }
400
403
  /** @internal */
401
- function wrapOnCallHandler(options, handler) {
404
+ function wrapOnCallHandler(options, handler, version) {
402
405
  return async (req, res) => {
403
406
  try {
404
407
  if (!isValidRequest(req)) {
@@ -413,7 +416,7 @@ function wrapOnCallHandler(options, handler) {
413
416
  // The original monkey-patched code lived in the functionsEmulatorRuntime
414
417
  // (link: https://github.com/firebase/firebase-tools/blob/accea7abda3cc9fa6bb91368e4895faf95281c60/src/emulator/functionsEmulatorRuntime.ts#L480)
415
418
  // and was not compatible with how monorepos separate out packages (see https://github.com/firebase/firebase-tools/issues/5210).
416
- if ((0, debug_1.isDebugFeatureEnabled)("skipTokenVerification") && handler.length === 2) {
419
+ if ((0, debug_1.isDebugFeatureEnabled)("skipTokenVerification") && version === "gcfv1") {
417
420
  const authContext = context.rawRequest.header(exports.CALLABLE_AUTH_HEADER);
418
421
  if (authContext) {
419
422
  logger.debug("Callable functions auth override", {
@@ -452,9 +455,14 @@ function wrapOnCallHandler(options, handler) {
452
455
  // pushes with FCM. In that case, the FCM APIs will validate the token.
453
456
  context.instanceIdToken = req.header("Firebase-Instance-ID-Token");
454
457
  }
458
+ const acceptsStreaming = req.header("accept") === "text/event-stream";
459
+ if (acceptsStreaming && version === "gcfv1") {
460
+ // streaming responses are not supported in v1 callable
461
+ throw new HttpsError("invalid-argument", "Unsupported Accept header 'text/event-stream'");
462
+ }
455
463
  const data = decode(req.body.data);
456
464
  let result;
457
- if (handler.length === 2) {
465
+ if (version === "gcfv1") {
458
466
  result = await handler(data, context);
459
467
  }
460
468
  else {
@@ -462,15 +470,36 @@ function wrapOnCallHandler(options, handler) {
462
470
  ...context,
463
471
  data,
464
472
  };
473
+ // TODO: set up optional heartbeat
474
+ const responseProxy = {
475
+ write(chunk) {
476
+ if (acceptsStreaming) {
477
+ const formattedData = encodeSSE({ message: chunk });
478
+ return res.write(formattedData);
479
+ }
480
+ // if client doesn't accept sse-protocol, response.write() is no-op.
481
+ },
482
+ acceptsStreaming,
483
+ };
484
+ if (acceptsStreaming) {
485
+ // SSE always responds with 200
486
+ res.status(200);
487
+ }
465
488
  // For some reason the type system isn't picking up that the handler
466
489
  // is a one argument function.
467
- result = await handler(arg);
490
+ result = await handler(arg, responseProxy);
468
491
  }
469
492
  // Encode the result as JSON to preserve types like Dates.
470
493
  result = encode(result);
471
494
  // If there was some result, encode it in the body.
472
495
  const responseBody = { result };
473
- res.status(200).send(responseBody);
496
+ if (acceptsStreaming) {
497
+ res.write(encodeSSE(responseBody));
498
+ res.end();
499
+ }
500
+ else {
501
+ res.status(200).send(responseBody);
502
+ }
474
503
  }
475
504
  catch (err) {
476
505
  let httpErr = err;
@@ -481,7 +510,12 @@ function wrapOnCallHandler(options, handler) {
481
510
  }
482
511
  const { status } = httpErr.httpErrorCode;
483
512
  const body = { error: httpErr.toJSON() };
484
- res.status(status).send(body);
513
+ if (version === "gcfv2" && req.header("accept") === "text/event-stream") {
514
+ res.send(encodeSSE(body));
515
+ }
516
+ else {
517
+ res.status(status).send(body);
518
+ }
485
519
  }
486
520
  };
487
521
  }
@@ -7,7 +7,7 @@ export { HttpsError };
7
7
  * @hidden
8
8
  * @alpha
9
9
  */
10
- export type AuthBlockingEventType = "beforeCreate" | "beforeSignIn";
10
+ export type AuthBlockingEventType = "beforeCreate" | "beforeSignIn" | "beforeSendEmail" | "beforeSendSms";
11
11
  /**
12
12
  * The `UserRecord` passed to Cloud Functions is the same
13
13
  * {@link https://firebase.google.com/docs/reference/admin/node/firebase-admin.auth.userrecord | UserRecord}
@@ -179,11 +179,13 @@ export interface AuthUserRecord {
179
179
  }
180
180
  /** The additional user info component of the auth event context */
181
181
  export interface AdditionalUserInfo {
182
- providerId: string;
182
+ providerId?: string;
183
183
  profile?: any;
184
184
  username?: string;
185
185
  isNewUser: boolean;
186
186
  recaptchaScore?: number;
187
+ email?: string;
188
+ phoneNumber?: string;
187
189
  }
188
190
  /** The credential component of the auth event context */
189
191
  export interface Credential {
@@ -198,6 +200,19 @@ export interface Credential {
198
200
  providerId: string;
199
201
  signInMethod: string;
200
202
  }
203
+ /**
204
+ * Possible types of emails as described by the GCIP backend, which can be:
205
+ * - A sign-in email
206
+ * - A password reset email
207
+ */
208
+ export type EmailType = "EMAIL_SIGN_IN" | "PASSWORD_RESET";
209
+ /**
210
+ * The type of SMS message, which can be:
211
+ * - A sign-in or sign up SMS message
212
+ * - A multi-factor sign-in SMS message
213
+ * - A multi-factor enrollment SMS message
214
+ */
215
+ export type SmsType = "SIGN_IN_OR_SIGN_UP" | "MULTI_FACTOR_SIGN_IN" | "MULTI_FACTOR_ENROLLMENT";
201
216
  /** Defines the auth event context for blocking events */
202
217
  export interface AuthEventContext extends EventContext {
203
218
  locale?: string;
@@ -205,15 +220,23 @@ export interface AuthEventContext extends EventContext {
205
220
  userAgent: string;
206
221
  additionalUserInfo?: AdditionalUserInfo;
207
222
  credential?: Credential;
223
+ emailType?: EmailType;
224
+ smsType?: SmsType;
208
225
  }
209
226
  /** Defines the auth event for 2nd gen blocking events */
210
227
  export interface AuthBlockingEvent extends AuthEventContext {
211
- data: AuthUserRecord;
228
+ data?: AuthUserRecord;
212
229
  }
213
- /**
214
- * The reCAPTCHA action options.
215
- */
230
+ /** The reCAPTCHA action options. */
216
231
  export type RecaptchaActionOptions = "ALLOW" | "BLOCK";
232
+ /** The handler response type for `beforeEmailSent` blocking events */
233
+ export interface BeforeEmailResponse {
234
+ recaptchaActionOverride?: RecaptchaActionOptions;
235
+ }
236
+ /** The handler response type for `beforeSmsSent` blocking events */
237
+ export interface BeforeSmsResponse {
238
+ recaptchaActionOverride?: RecaptchaActionOptions;
239
+ }
217
240
  /** The handler response type for `beforeCreate` blocking events */
218
241
  export interface BeforeCreateResponse {
219
242
  displayName?: string;
@@ -227,3 +250,9 @@ export interface BeforeCreateResponse {
227
250
  export interface BeforeSignInResponse extends BeforeCreateResponse {
228
251
  sessionClaims?: object;
229
252
  }
253
+ export type MaybeAsync<T> = T | Promise<T>;
254
+ export type HandlerV1 = (userOrContext: AuthUserRecord | AuthEventContext, context?: AuthEventContext) => MaybeAsync<BeforeCreateResponse | BeforeSignInResponse | BeforeEmailResponse | BeforeSmsResponse | void>;
255
+ export type HandlerV2 = (event: AuthBlockingEvent) => MaybeAsync<BeforeCreateResponse | BeforeSignInResponse | BeforeEmailResponse | BeforeSmsResponse | void>;
256
+ export type AuthBlockingEventHandler = (HandlerV1 | HandlerV2) & {
257
+ platform: "gcfv1" | "gcfv2";
258
+ };
@@ -49,6 +49,8 @@ const CLAIMS_MAX_PAYLOAD_SIZE = 1000;
49
49
  const EVENT_MAPPING = {
50
50
  beforeCreate: "providers/cloud.auth/eventTypes/user.beforeCreate",
51
51
  beforeSignIn: "providers/cloud.auth/eventTypes/user.beforeSignIn",
52
+ beforeSendEmail: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
53
+ beforeSendSms: "providers/cloud.auth/eventTypes/user.beforeSendSms",
52
54
  };
53
55
  /**
54
56
  * Helper class to create the user metadata in a `UserRecord` object.
@@ -302,6 +304,8 @@ function parseAdditionalUserInfo(decodedJWT) {
302
304
  username,
303
305
  isNewUser: decodedJWT.event_type === "beforeCreate" ? true : false,
304
306
  recaptchaScore: decodedJWT.recaptcha_score,
307
+ email: decodedJWT.email,
308
+ phoneNumber: decodedJWT.phone_number,
305
309
  };
306
310
  }
307
311
  /**
@@ -372,6 +376,8 @@ function parseAuthEventContext(decodedJWT, projectId, time = new Date().getTime(
372
376
  timestamp: new Date(decodedJWT.iat * 1000).toUTCString(),
373
377
  additionalUserInfo: parseAdditionalUserInfo(decodedJWT),
374
378
  credential: parseAuthCredential(decodedJWT, time),
379
+ emailType: decodedJWT.email_type,
380
+ smsType: decodedJWT.sms_type,
375
381
  params: {},
376
382
  };
377
383
  }
@@ -443,15 +449,20 @@ function wrapHandler(eventType, handler) {
443
449
  }
444
450
  const decodedPayload = (0, debug_1.isDebugFeatureEnabled)("skipTokenVerification")
445
451
  ? unsafeDecodeAuthBlockingToken(req.body.data.jwt)
446
- : handler.length === 2
452
+ : handler.platform === "gcfv1"
447
453
  ? await auth.getAuth((0, app_1.getApp)())._verifyAuthBlockingToken(req.body.data.jwt)
448
454
  : await auth.getAuth((0, app_1.getApp)())._verifyAuthBlockingToken(req.body.data.jwt, "run.app");
449
- const authUserRecord = parseAuthUserRecord(decodedPayload.user_record);
455
+ let authUserRecord;
456
+ if (decodedPayload.event_type === "beforeCreate" ||
457
+ decodedPayload.event_type === "beforeSignIn") {
458
+ authUserRecord = parseAuthUserRecord(decodedPayload.user_record);
459
+ }
450
460
  const authEventContext = parseAuthEventContext(decodedPayload, projectId);
451
461
  let authResponse;
452
- if (handler.length === 2) {
453
- authResponse =
454
- (await handler(authUserRecord, authEventContext)) || undefined;
462
+ if (handler.platform === "gcfv1") {
463
+ authResponse = authUserRecord
464
+ ? (await handler(authUserRecord, authEventContext)) || undefined
465
+ : (await handler(authEventContext)) || undefined;
455
466
  }
456
467
  else {
457
468
  authResponse =
@@ -1,4 +1,4 @@
1
- import { AuthEventContext, AuthUserRecord, BeforeCreateResponse, BeforeSignInResponse, HttpsError, UserInfo, UserRecord, userRecordConstructor, UserRecordMetadata } from "../../common/providers/identity";
1
+ import { AuthEventContext, AuthUserRecord, BeforeCreateResponse, BeforeEmailResponse, BeforeSignInResponse, BeforeSmsResponse, HttpsError, MaybeAsync, UserInfo, UserRecord, userRecordConstructor, UserRecordMetadata } from "../../common/providers/identity";
2
2
  import { BlockingFunction, CloudFunction, EventContext } from "../cloud-functions";
3
3
  export { UserRecord, UserInfo, UserRecordMetadata, userRecordConstructor };
4
4
  export { HttpsError };
@@ -57,7 +57,7 @@ export declare class UserBuilder {
57
57
  *
58
58
  * @public
59
59
  */
60
- beforeCreate(handler: (user: AuthUserRecord, context: AuthEventContext) => BeforeCreateResponse | void | Promise<BeforeCreateResponse> | Promise<void>): BlockingFunction;
60
+ beforeCreate(handler: (user: AuthUserRecord, context: AuthEventContext) => MaybeAsync<BeforeCreateResponse | void>): BlockingFunction;
61
61
  /**
62
62
  * Blocks request to sign-in a Firebase Auth user.
63
63
  *
@@ -65,7 +65,9 @@ export declare class UserBuilder {
65
65
  *
66
66
  * @public
67
67
  */
68
- beforeSignIn(handler: (user: AuthUserRecord, context: AuthEventContext) => BeforeSignInResponse | void | Promise<BeforeSignInResponse> | Promise<void>): BlockingFunction;
68
+ beforeSignIn(handler: (user: AuthUserRecord, context: AuthEventContext) => MaybeAsync<BeforeSignInResponse | void>): BlockingFunction;
69
+ beforeEmail(handler: (context: AuthEventContext) => MaybeAsync<BeforeEmailResponse | void>): BlockingFunction;
70
+ beforeSms(handler: (context: AuthEventContext) => MaybeAsync<BeforeSmsResponse | void>): BlockingFunction;
69
71
  private onOperation;
70
72
  private beforeOperation;
71
73
  }
@@ -108,6 +108,12 @@ class UserBuilder {
108
108
  beforeSignIn(handler) {
109
109
  return this.beforeOperation(handler, "beforeSignIn");
110
110
  }
111
+ beforeEmail(handler) {
112
+ return this.beforeOperation(handler, "beforeSendEmail");
113
+ }
114
+ beforeSms(handler) {
115
+ return this.beforeOperation(handler, "beforeSendSms");
116
+ }
111
117
  onOperation(handler, eventType) {
112
118
  return (0, cloud_functions_1.makeCloudFunction)({
113
119
  handler,
@@ -126,10 +132,8 @@ class UserBuilder {
126
132
  const accessToken = ((_b = (_a = this.userOptions) === null || _a === void 0 ? void 0 : _a.blockingOptions) === null || _b === void 0 ? void 0 : _b.accessToken) || false;
127
133
  const idToken = ((_d = (_c = this.userOptions) === null || _c === void 0 ? void 0 : _c.blockingOptions) === null || _d === void 0 ? void 0 : _d.idToken) || false;
128
134
  const refreshToken = ((_f = (_e = this.userOptions) === null || _e === void 0 ? void 0 : _e.blockingOptions) === null || _f === void 0 ? void 0 : _f.refreshToken) || false;
129
- // Create our own function that just calls the provided function so we know for sure that
130
- // handler takes two arguments. This is something common/providers/identity depends on.
131
- const wrappedHandler = (user, context) => handler(user, context);
132
- const func = (0, identity_1.wrapHandler)(eventType, wrappedHandler);
135
+ const annotatedHandler = Object.assign(handler, { platform: "gcfv1" });
136
+ const func = (0, identity_1.wrapHandler)(eventType, annotatedHandler);
133
137
  const legacyEventType = `providers/cloud.auth/eventTypes/user.${eventType}`;
134
138
  func.__trigger = {
135
139
  labels: {},
@@ -70,9 +70,8 @@ function _onRequestWithOptions(handler, options) {
70
70
  exports._onRequestWithOptions = _onRequestWithOptions;
71
71
  /** @internal */
72
72
  function _onCallWithOptions(handler, options) {
73
- // onCallHandler sniffs the function length of the passed-in callback
74
- // and the user could have only tried to listen to data. Wrap their handler
75
- // in another handler to avoid accidentally triggering the v2 API
73
+ // fix the length of handler to make the call to handler consistent
74
+ // in the onCallHandler
76
75
  const fixedLen = (data, context) => {
77
76
  return (0, onInit_1.withInit)(handler)(data, context);
78
77
  };
@@ -80,7 +79,7 @@ function _onCallWithOptions(handler, options) {
80
79
  enforceAppCheck: options.enforceAppCheck,
81
80
  consumeAppCheckToken: options.consumeAppCheckToken,
82
81
  cors: { origin: true, methods: "POST" },
83
- }, fixedLen));
82
+ }, fixedLen, "gcfv1"));
84
83
  func.__trigger = {
85
84
  labels: {},
86
85
  ...(0, cloud_functions_1.optionsToTrigger)(options),
@@ -1,6 +1,6 @@
1
1
  import * as express from "express";
2
2
  import { ResetValue } from "../../common/options";
3
- import { CallableRequest, FunctionsErrorCode, HttpsError, Request } from "../../common/providers/https";
3
+ import { CallableRequest, CallableProxyResponse, FunctionsErrorCode, HttpsError, Request } from "../../common/providers/https";
4
4
  import { ManifestEndpoint } from "../../runtime/manifest";
5
5
  import { GlobalOptions, SupportedRegion } from "../options";
6
6
  import { Expression } from "../../params";
@@ -175,10 +175,10 @@ export declare function onRequest(handler: (request: Request, response: express.
175
175
  * @param handler - A function that takes a {@link https.CallableRequest}.
176
176
  * @returns A function that you can export and deploy.
177
177
  */
178
- export declare function onCall<T = any, Return = any | Promise<any>>(opts: CallableOptions, handler: (request: CallableRequest<T>) => Return): CallableFunction<T, Return extends Promise<unknown> ? Return : Promise<Return>>;
178
+ export declare function onCall<T = any, Return = any | Promise<any>>(opts: CallableOptions, handler: (request: CallableRequest<T>, response?: CallableProxyResponse) => Return): CallableFunction<T, Return extends Promise<unknown> ? Return : Promise<Return>>;
179
179
  /**
180
180
  * Declares a callable method for clients to call using a Firebase SDK.
181
181
  * @param handler - A function that takes a {@link https.CallableRequest}.
182
182
  * @returns A function that you can export and deploy.
183
183
  */
184
- export declare function onCall<T = any, Return = any | Promise<any>>(handler: (request: CallableRequest<T>) => Return): CallableFunction<T, Return extends Promise<unknown> ? Return : Promise<Return>>;
184
+ export declare function onCall<T = any, Return = any | Promise<any>>(handler: (request: CallableRequest<T>, response?: CallableProxyResponse) => Return): CallableFunction<T, Return extends Promise<unknown> ? Return : Promise<Return>>;
@@ -130,15 +130,14 @@ function onCall(optsOrHandler, handler) {
130
130
  if (Array.isArray(origin) && origin.length === 1) {
131
131
  origin = origin[0];
132
132
  }
133
- // onCallHandler sniffs the function length to determine which API to present.
134
- // fix the length to prevent api versions from being mismatched.
135
- const fixedLen = (req) => (0, onInit_1.withInit)(handler)(req);
133
+ // fix the length of handler to make the call to handler consistent
134
+ const fixedLen = (req, resp) => (0, onInit_1.withInit)(handler)(req, resp);
136
135
  let func = (0, https_1.onCallHandler)({
137
136
  cors: { origin, methods: "POST" },
138
137
  enforceAppCheck: (_a = opts.enforceAppCheck) !== null && _a !== void 0 ? _a : options.getGlobalOptions().enforceAppCheck,
139
138
  consumeAppCheckToken: opts.consumeAppCheckToken,
140
- }, fixedLen);
141
- func = (0, trace_1.wrapTraceContext)(func);
139
+ }, fixedLen, "gcfv2");
140
+ func = (0, trace_1.wrapTraceContext)((0, onInit_1.withInit)(func));
142
141
  Object.defineProperty(func, "__trigger", {
143
142
  get: () => {
144
143
  const baseOpts = options.optionsToTriggerAnnotations(options.getGlobalOptions());
@@ -3,7 +3,7 @@
3
3
  * @packageDocumentation
4
4
  */
5
5
  import { ResetValue } from "../../common/options";
6
- import { AuthBlockingEvent, AuthBlockingEventType, AuthUserRecord, BeforeCreateResponse, BeforeSignInResponse, HttpsError } from "../../common/providers/identity";
6
+ import { AuthBlockingEvent, AuthBlockingEventType, AuthUserRecord, BeforeCreateResponse, BeforeSignInResponse, BeforeEmailResponse, BeforeSmsResponse, HandlerV2, HttpsError, MaybeAsync } from "../../common/providers/identity";
7
7
  import { BlockingFunction } from "../../v1/cloud-functions";
8
8
  import { Expression } from "../../params";
9
9
  import * as options from "../options";
@@ -107,27 +107,49 @@ export interface BlockingOptions {
107
107
  }
108
108
  /**
109
109
  * Handles an event that is triggered before a user is created.
110
- * @param handler - Event handler which is run every time before a user is created
110
+ * @param handler - Event handler which is run every time before a user is created.
111
111
  */
112
- export declare function beforeUserCreated(handler: (event: AuthBlockingEvent) => BeforeCreateResponse | Promise<BeforeCreateResponse> | void | Promise<void>): BlockingFunction;
112
+ export declare function beforeUserCreated(handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeCreateResponse | void>): BlockingFunction;
113
113
  /**
114
114
  * Handles an event that is triggered before a user is created.
115
- * @param opts - Object containing function options
116
- * @param handler - Event handler which is run every time before a user is created
115
+ * @param opts - Object containing function options.
116
+ * @param handler - Event handler which is run every time before a user is created.
117
117
  */
118
- export declare function beforeUserCreated(opts: BlockingOptions, handler: (event: AuthBlockingEvent) => BeforeCreateResponse | Promise<BeforeCreateResponse> | void | Promise<void>): BlockingFunction;
118
+ export declare function beforeUserCreated(opts: BlockingOptions, handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeCreateResponse | void>): BlockingFunction;
119
119
  /**
120
120
  * Handles an event that is triggered before a user is signed in.
121
- * @param handler - Event handler which is run every time before a user is signed in
121
+ * @param handler - Event handler which is run every time before a user is signed in.
122
122
  */
123
- export declare function beforeUserSignedIn(handler: (event: AuthBlockingEvent) => BeforeSignInResponse | Promise<BeforeSignInResponse> | void | Promise<void>): BlockingFunction;
123
+ export declare function beforeUserSignedIn(handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeSignInResponse | void>): BlockingFunction;
124
124
  /**
125
125
  * Handles an event that is triggered before a user is signed in.
126
- * @param opts - Object containing function options
127
- * @param handler - Event handler which is run every time before a user is signed in
126
+ * @param opts - Object containing function options.
127
+ * @param handler - Event handler which is run every time before a user is signed in.
128
128
  */
129
- export declare function beforeUserSignedIn(opts: BlockingOptions, handler: (event: AuthBlockingEvent) => BeforeSignInResponse | Promise<BeforeSignInResponse> | void | Promise<void>): BlockingFunction;
129
+ export declare function beforeUserSignedIn(opts: BlockingOptions, handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeSignInResponse | void>): BlockingFunction;
130
+ /**
131
+ * Handles an event that is triggered before an email is sent to a user.
132
+ * @param handler - Event handler that is run before an email is sent to a user.
133
+ */
134
+ export declare function beforeEmailSent(handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeEmailResponse | void>): BlockingFunction;
135
+ /**
136
+ * Handles an event that is triggered before an email is sent to a user.
137
+ * @param opts - Object containing function options.
138
+ * @param handler - Event handler that is run before an email is sent to a user.
139
+ */
140
+ export declare function beforeEmailSent(opts: Omit<BlockingOptions, "idToken" | "accessToken" | "refreshToken">, handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeEmailResponse | void>): BlockingFunction;
141
+ /**
142
+ * Handles an event that is triggered before an SMS is sent to a user.
143
+ * @param handler - Event handler that is run before an SMS is sent to a user.
144
+ */
145
+ export declare function beforeSmsSent(handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeSmsResponse | void>): BlockingFunction;
146
+ /**
147
+ * Handles an event that is triggered before an SMS is sent to a user.
148
+ * @param opts - Object containing function options.
149
+ * @param handler - Event handler that is run before an SMS is sent to a user.
150
+ */
151
+ export declare function beforeSmsSent(opts: Omit<BlockingOptions, "idToken" | "accessToken" | "refreshToken">, handler: (event: AuthBlockingEvent) => MaybeAsync<BeforeSmsResponse | void>): BlockingFunction;
130
152
  /** @hidden */
131
- export declare function beforeOperation(eventType: AuthBlockingEventType, optsOrHandler: BlockingOptions | ((event: AuthBlockingEvent) => BeforeCreateResponse | BeforeSignInResponse | void | Promise<BeforeCreateResponse> | Promise<BeforeSignInResponse> | Promise<void>), handler: (event: AuthBlockingEvent) => BeforeCreateResponse | BeforeSignInResponse | void | Promise<BeforeCreateResponse> | Promise<BeforeSignInResponse> | Promise<void>): BlockingFunction;
153
+ export declare function beforeOperation(eventType: AuthBlockingEventType, optsOrHandler: BlockingOptions | ((event: AuthBlockingEvent) => MaybeAsync<BeforeCreateResponse | BeforeSignInResponse | BeforeEmailResponse | BeforeSmsResponse | void>), handler: HandlerV2): BlockingFunction;
132
154
  /** @hidden */
133
155
  export declare function getOpts(blockingOptions: BlockingOptions): InternalOptions;
@@ -21,7 +21,7 @@
21
21
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  // SOFTWARE.
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.getOpts = exports.beforeOperation = exports.beforeUserSignedIn = exports.beforeUserCreated = exports.HttpsError = void 0;
24
+ exports.getOpts = exports.beforeOperation = exports.beforeSmsSent = exports.beforeEmailSent = exports.beforeUserSignedIn = exports.beforeUserCreated = exports.HttpsError = void 0;
25
25
  const identity_1 = require("../../common/providers/identity");
26
26
  Object.defineProperty(exports, "HttpsError", { enumerable: true, get: function () { return identity_1.HttpsError; } });
27
27
  const trace_1 = require("../trace");
@@ -29,9 +29,9 @@ const manifest_1 = require("../../runtime/manifest");
29
29
  const options = require("../options");
30
30
  const onInit_1 = require("../../common/onInit");
31
31
  /**
32
- * Handles an event that is triggered before a user is created
33
- * @param optsOrHandler - Either an object containing function options, or an event handler (run before user creation)
34
- * @param handler? - If defined, an event handler which is run every time before a user is created
32
+ * Handles an event that is triggered before a user is created.
33
+ * @param optsOrHandler - Either an object containing function options, or an event handler (run before user creation).
34
+ * @param handler? - If defined, an event handler which is run every time before a user is created.
35
35
  */
36
36
  function beforeUserCreated(optsOrHandler, handler) {
37
37
  return beforeOperation("beforeCreate", optsOrHandler, handler);
@@ -39,24 +39,42 @@ function beforeUserCreated(optsOrHandler, handler) {
39
39
  exports.beforeUserCreated = beforeUserCreated;
40
40
  /**
41
41
  * Handles an event that is triggered before a user is signed in.
42
- * @param optsOrHandler - Either an object containing function options, or an event handler (run before user signin)
43
- * @param handler - Event handler which is run every time before a user is signed in
42
+ * @param optsOrHandler - Either an object containing function options, or an event handler (run before user signin).
43
+ * @param handler - Event handler which is run every time before a user is signed in.
44
44
  */
45
45
  function beforeUserSignedIn(optsOrHandler, handler) {
46
46
  return beforeOperation("beforeSignIn", optsOrHandler, handler);
47
47
  }
48
48
  exports.beforeUserSignedIn = beforeUserSignedIn;
49
+ /**
50
+ * Handles an event that is triggered before an email is sent to a user.
51
+ * @param optsOrHandler- Either an object containing function options, or an event handler that is run before an email is sent to a user.
52
+ * @param handler - Event handler that is run before an email is sent to a user.
53
+ */
54
+ function beforeEmailSent(optsOrHandler, handler) {
55
+ return beforeOperation("beforeSendEmail", optsOrHandler, handler);
56
+ }
57
+ exports.beforeEmailSent = beforeEmailSent;
58
+ /**
59
+ * Handles an event that is triggered before an SMS is sent to a user.
60
+ * @param optsOrHandler - Either an object containing function options, or an event handler that is run before an SMS is sent to a user.
61
+ * @param handler - Event handler that is run before an SMS is sent to a user.
62
+ */
63
+ function beforeSmsSent(optsOrHandler, handler) {
64
+ return beforeOperation("beforeSendSms", optsOrHandler, handler);
65
+ }
66
+ exports.beforeSmsSent = beforeSmsSent;
49
67
  /** @hidden */
50
68
  function beforeOperation(eventType, optsOrHandler, handler) {
51
69
  if (!handler || typeof optsOrHandler === "function") {
52
70
  handler = optsOrHandler;
53
71
  optsOrHandler = {};
54
72
  }
55
- const { opts, accessToken, idToken, refreshToken } = getOpts(optsOrHandler);
73
+ const { opts, ...blockingOptions } = getOpts(optsOrHandler);
56
74
  // Create our own function that just calls the provided function so we know for sure that
57
75
  // handler takes one argument. This is something common/providers/identity depends on.
58
- const wrappedHandler = (event) => handler(event);
59
- const func = (0, trace_1.wrapTraceContext)((0, onInit_1.withInit)((0, identity_1.wrapHandler)(eventType, wrappedHandler)));
76
+ const annotatedHandler = Object.assign(handler, { platform: "gcfv2" });
77
+ const func = (0, trace_1.wrapTraceContext)((0, onInit_1.withInit)((0, identity_1.wrapHandler)(eventType, annotatedHandler)));
60
78
  const legacyEventType = `providers/cloud.auth/eventTypes/user.${eventType}`;
61
79
  /** Endpoint */
62
80
  const baseOptsEndpoint = options.optionsToEndpoint(options.getGlobalOptions());
@@ -73,9 +91,7 @@ function beforeOperation(eventType, optsOrHandler, handler) {
73
91
  blockingTrigger: {
74
92
  eventType: legacyEventType,
75
93
  options: {
76
- accessToken,
77
- idToken,
78
- refreshToken,
94
+ ...((eventType === "beforeCreate" || eventType === "beforeSignIn") && blockingOptions),
79
95
  },
80
96
  },
81
97
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-functions",
3
- "version": "6.0.1",
3
+ "version": "6.1.1",
4
4
  "description": "Firebase SDK for Cloud Functions",
5
5
  "keywords": [
6
6
  "firebase",
@@ -270,9 +270,9 @@
270
270
  },
271
271
  "dependencies": {
272
272
  "@types/cors": "^2.8.5",
273
- "@types/express": "4.17.3",
273
+ "@types/express": "^4.17.21",
274
274
  "cors": "^2.8.5",
275
- "express": "^4.17.1",
275
+ "express": "^4.21.0",
276
276
  "protobufjs": "^7.2.2"
277
277
  },
278
278
  "devDependencies": {
@@ -299,7 +299,7 @@
299
299
  "eslint-config-prettier": "^8.3.0",
300
300
  "eslint-plugin-jsdoc": "^39.2.9",
301
301
  "eslint-plugin-prettier": "^4.0.0",
302
- "firebase-admin": "^12.1.0",
302
+ "firebase-admin": "^13.0.0",
303
303
  "js-yaml": "^3.13.1",
304
304
  "jsdom": "^16.2.1",
305
305
  "jsonwebtoken": "^9.0.0",
@@ -319,7 +319,7 @@
319
319
  "yargs": "^15.3.1"
320
320
  },
321
321
  "peerDependencies": {
322
- "firebase-admin": "^11.10.0 || ^12.0.0"
322
+ "firebase-admin": "^11.10.0 || ^12.0.0 || ^13.0.0"
323
323
  },
324
324
  "engines": {
325
325
  "node": ">=14.10.0"