firebase-functions 3.19.0 → 3.21.0

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.
Files changed (46) hide show
  1. package/lib/cloud-functions.d.ts +8 -0
  2. package/lib/cloud-functions.js +4 -7
  3. package/lib/common/providers/https.d.ts +20 -49
  4. package/lib/common/providers/https.js +7 -45
  5. package/lib/common/providers/identity.d.ts +193 -4
  6. package/lib/common/providers/identity.js +402 -28
  7. package/lib/common/providers/tasks.d.ts +58 -0
  8. package/lib/common/providers/tasks.js +77 -0
  9. package/lib/function-builder.d.ts +5 -2
  10. package/lib/function-builder.js +7 -2
  11. package/lib/handler-builder.d.ts +13 -2
  12. package/lib/handler-builder.js +17 -4
  13. package/lib/index.d.ts +2 -1
  14. package/lib/index.js +3 -1
  15. package/lib/providers/auth.d.ts +19 -6
  16. package/lib/providers/auth.js +60 -8
  17. package/lib/providers/https.d.ts +2 -44
  18. package/lib/providers/https.js +1 -49
  19. package/lib/providers/tasks.d.ts +46 -0
  20. package/lib/providers/tasks.js +75 -0
  21. package/lib/runtime/loader.js +9 -7
  22. package/lib/runtime/manifest.d.ts +8 -10
  23. package/lib/runtime/manifest.js +21 -0
  24. package/lib/v2/core.d.ts +3 -21
  25. package/lib/v2/index.d.ts +4 -1
  26. package/lib/v2/index.js +7 -1
  27. package/lib/v2/options.d.ts +13 -2
  28. package/lib/v2/options.js +22 -30
  29. package/lib/v2/providers/alerts/alerts.d.ts +15 -7
  30. package/lib/v2/providers/alerts/alerts.js +4 -10
  31. package/lib/v2/providers/alerts/appDistribution.d.ts +11 -11
  32. package/lib/v2/providers/alerts/billing.d.ts +17 -11
  33. package/lib/v2/providers/alerts/crashlytics.d.ts +62 -29
  34. package/lib/v2/providers/eventarc.d.ts +32 -0
  35. package/lib/v2/providers/eventarc.js +65 -0
  36. package/lib/v2/providers/https.d.ts +8 -23
  37. package/lib/v2/providers/https.js +3 -48
  38. package/lib/v2/providers/identity.d.ts +22 -0
  39. package/lib/v2/providers/identity.js +73 -0
  40. package/lib/v2/providers/pubsub.d.ts +3 -3
  41. package/lib/v2/providers/pubsub.js +2 -5
  42. package/lib/v2/providers/storage.d.ts +17 -13
  43. package/lib/v2/providers/storage.js +5 -4
  44. package/lib/v2/providers/tasks.d.ts +22 -0
  45. package/lib/v2/providers/tasks.js +88 -0
  46. package/package.json +42 -15
@@ -180,6 +180,10 @@ export interface Resource {
180
180
  export interface TriggerAnnotated {
181
181
  __trigger: {
182
182
  availableMemoryMb?: number;
183
+ blockingTrigger?: {
184
+ eventType: string;
185
+ options?: Record<string, unknown>;
186
+ };
183
187
  eventTrigger?: {
184
188
  eventType: string;
185
189
  resource: string;
@@ -227,6 +231,10 @@ export interface Runnable<T> {
227
231
  * arguments.
228
232
  */
229
233
  export declare type HttpsFunction = TriggerAnnotated & EndpointAnnotated & ((req: Request, resp: Response) => void | Promise<void>);
234
+ /**
235
+ * The Cloud Function type for Blocking triggers.
236
+ */
237
+ export declare type BlockingFunction = HttpsFunction;
230
238
  /**
231
239
  * The Cloud Function type for all non-HTTPS triggers. This should be exported
232
240
  * from your JavaScript file to define a Cloud Function.
@@ -180,12 +180,9 @@ function makeCloudFunction({ after = () => { }, before = () => { }, contextOnlyH
180
180
  else {
181
181
  endpoint.eventTrigger = {
182
182
  eventType: legacyEventType || provider + '.' + eventType,
183
- eventFilters: [
184
- {
185
- attribute: 'resource',
186
- value: triggerResource(),
187
- },
188
- ],
183
+ eventFilters: {
184
+ resource: triggerResource(),
185
+ },
189
186
  retry: !!options.failurePolicy,
190
187
  };
191
188
  }
@@ -289,7 +286,7 @@ function optionsToEndpoint(options) {
289
286
  (0, encoding_1.copyIfPresent)(endpoint, options, 'minInstances', 'maxInstances', 'ingressSettings', 'labels', 'timeoutSeconds');
290
287
  (0, encoding_1.convertIfPresent)(endpoint, options, 'region', 'regions');
291
288
  (0, encoding_1.convertIfPresent)(endpoint, options, 'serviceAccountEmail', 'serviceAccount', (sa) => sa);
292
- (0, encoding_1.convertIfPresent)(endpoint, options, 'secretEnvironmentVariables', 'secrets', (secrets) => secrets.map((secret) => ({ secret, key: secret })));
289
+ (0, encoding_1.convertIfPresent)(endpoint, options, 'secretEnvironmentVariables', 'secrets', (secrets) => secrets.map((secret) => ({ key: secret })));
293
290
  if (options === null || options === void 0 ? void 0 : options.vpcConnector) {
294
291
  endpoint.vpc = { connector: options.vpcConnector };
295
292
  (0, encoding_1.convertIfPresent)(endpoint.vpc, options, 'egressSettings', 'vpcConnectorEgressSettings');
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import * as express from 'express';
3
3
  import * as firebase from 'firebase-admin';
4
+ import { TaskContext } from './tasks';
4
5
  /** @hidden */
5
6
  export interface Request extends express.Request {
6
7
  rawBody: Buffer;
@@ -107,55 +108,6 @@ export interface CallableRequest<T = any> {
107
108
  */
108
109
  rawRequest: Request;
109
110
  }
110
- /** How a task should be retried in the event of a non-2xx return. */
111
- export interface TaskRetryConfig {
112
- /**
113
- * Maximum number of times a request should be attempted.
114
- * If left unspecified, will default to 3.
115
- */
116
- maxAttempts?: number;
117
- /**
118
- * The maximum amount of time to wait between attempts.
119
- * If left unspecified will default to 1hr.
120
- */
121
- maxBackoffSeconds?: number;
122
- /**
123
- * The maximum number of times to double the backoff between
124
- * retries. If left unspecified will default to 16.
125
- */
126
- maxDoublings?: number;
127
- /**
128
- * The minimum time to wait between attempts. If left unspecified
129
- * will default to 100ms.
130
- */
131
- minBackoffSeconds?: number;
132
- }
133
- /** How congestion control should be applied to the function. */
134
- export interface TaskRateLimits {
135
- maxBurstSize?: number;
136
- maxConcurrentDispatches?: number;
137
- maxDispatchesPerSecond?: number;
138
- }
139
- /** Metadata about a call to a Task Queue function. */
140
- export interface TaskContext {
141
- /**
142
- * The result of decoding and verifying an ODIC token.
143
- */
144
- auth?: AuthData;
145
- }
146
- /**
147
- * The request used to call a Task Queue function.
148
- */
149
- export interface TaskRequest<T = any> {
150
- /**
151
- * The parameters used by a client when calling this function.
152
- */
153
- data: T;
154
- /**
155
- * The result of decoding and verifying an ODIC token.
156
- */
157
- auth?: AuthData;
158
- }
159
111
  /**
160
112
  * The set of Firebase Functions status codes. The codes are the same at the
161
113
  * ones exposed by gRPC here:
@@ -232,6 +184,14 @@ export declare class HttpsError extends Error {
232
184
  constructor(code: FunctionsErrorCode, message: string, details?: unknown);
233
185
  toJSON(): HttpErrorWireFormat;
234
186
  }
187
+ /** @hidden */
188
+ interface HttpRequest extends Request {
189
+ body: {
190
+ data: any;
191
+ };
192
+ }
193
+ /** @hidden */
194
+ export declare function isValidRequest(req: Request): req is HttpRequest;
235
195
  /**
236
196
  * Encodes arbitrary data in our special format for JSON.
237
197
  * This is exposed only for testing.
@@ -244,4 +204,15 @@ export declare function encode(data: any): any;
244
204
  */
245
205
  /** @hidden */
246
206
  export declare function decode(data: any): any;
207
+ /**
208
+ * Be careful when changing token status values.
209
+ *
210
+ * Users are encouraged to setup log-based metric based on these values, and
211
+ * changing their values may cause their metrics to break.
212
+ *
213
+ */
214
+ /** @hidden */
215
+ declare type TokenStatus = 'MISSING' | 'VALID' | 'INVALID';
216
+ /** @interanl */
217
+ export declare function checkAuthToken(req: Request, ctx: CallableContext | TaskContext): Promise<TokenStatus>;
247
218
  export {};
@@ -21,13 +21,13 @@
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.onDispatchHandler = exports.onCallHandler = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.decode = exports.encode = exports.HttpsError = void 0;
24
+ exports.onCallHandler = exports.checkAuthToken = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.unsafeDecodeToken = exports.decode = exports.encode = exports.isValidRequest = exports.HttpsError = void 0;
25
25
  const cors = require("cors");
26
26
  const logger = require("../../logger");
27
27
  // TODO(inlined): Decide whether we want to un-version apps or whether we want a
28
28
  // different strategy
29
29
  const apps_1 = require("../../apps");
30
- const debug_1 = require("../../common/debug");
30
+ const debug_1 = require("../debug");
31
31
  const JWT_REGEX = /^[a-zA-Z0-9\-_=]+?\.[a-zA-Z0-9\-_=]+?\.([a-zA-Z0-9\-_=]+)?$/;
32
32
  /**
33
33
  * Standard error codes and HTTP statuses for different ways a request can fail,
@@ -100,7 +100,7 @@ function isValidRequest(req) {
100
100
  // If it has a charset, just ignore it for now.
101
101
  const semiColon = contentType.indexOf(';');
102
102
  if (semiColon >= 0) {
103
- contentType = contentType.substr(0, semiColon).trim();
103
+ contentType = contentType.slice(0, semiColon).trim();
104
104
  }
105
105
  if (contentType !== 'application/json') {
106
106
  logger.warn('Request has incorrect Content-Type.', contentType);
@@ -120,6 +120,7 @@ function isValidRequest(req) {
120
120
  }
121
121
  return true;
122
122
  }
123
+ exports.isValidRequest = isValidRequest;
123
124
  /** @hidden */
124
125
  const LONG_TYPE = 'type.googleapis.com/google.protobuf.Int64Value';
125
126
  /** @hidden */
@@ -208,6 +209,7 @@ function decode(data) {
208
209
  return data;
209
210
  }
210
211
  exports.decode = decode;
212
+ /** @internal */
211
213
  function unsafeDecodeToken(token) {
212
214
  if (!JWT_REGEX.test(token)) {
213
215
  return {};
@@ -227,6 +229,7 @@ function unsafeDecodeToken(token) {
227
229
  }
228
230
  return payload;
229
231
  }
232
+ exports.unsafeDecodeToken = unsafeDecodeToken;
230
233
  /**
231
234
  * Decode, but not verify, a Auth ID token.
232
235
  *
@@ -329,6 +332,7 @@ async function checkAuthToken(req, ctx) {
329
332
  }
330
333
  }
331
334
  }
335
+ exports.checkAuthToken = checkAuthToken;
332
336
  /** @internal */
333
337
  async function checkAppCheckToken(req, ctx) {
334
338
  const appCheck = req.header('X-Firebase-AppCheck');
@@ -426,45 +430,3 @@ function wrapOnCallHandler(options, handler) {
426
430
  }
427
431
  };
428
432
  }
429
- /** @internal */
430
- function onDispatchHandler(handler) {
431
- return async (req, res) => {
432
- try {
433
- if (!isValidRequest(req)) {
434
- logger.error('Invalid request, unable to process.');
435
- throw new HttpsError('invalid-argument', 'Bad Request');
436
- }
437
- const context = {};
438
- const status = await checkAuthToken(req, context);
439
- // Note: this should never happen since task queue functions are guarded by IAM.
440
- if (status === 'INVALID') {
441
- throw new HttpsError('unauthenticated', 'Unauthenticated');
442
- }
443
- const data = decode(req.body.data);
444
- if (handler.length === 2) {
445
- await handler(data, context);
446
- }
447
- else {
448
- const arg = {
449
- ...context,
450
- data,
451
- };
452
- // For some reason the type system isn't picking up that the handler
453
- // is a one argument function.
454
- await handler(arg);
455
- }
456
- res.status(204).end();
457
- }
458
- catch (err) {
459
- if (!(err instanceof HttpsError)) {
460
- // This doesn't count as an 'explicit' error.
461
- logger.error('Unhandled error', err);
462
- err = new HttpsError('internal', 'INTERNAL');
463
- }
464
- const { status } = err.httpErrorCode;
465
- const body = { error: err.toJSON() };
466
- res.status(status).send(body);
467
- }
468
- };
469
- }
470
- exports.onDispatchHandler = onDispatchHandler;
@@ -1,4 +1,9 @@
1
1
  import * as firebase from 'firebase-admin';
2
+ import { EventContext } from '../../cloud-functions';
3
+ import { HttpsError } from './https';
4
+ export { HttpsError };
5
+ /** Shorthand auth blocking events from GCIP. */
6
+ export declare type AuthBlockingEventType = 'beforeCreate' | 'beforeSignIn';
2
7
  /**
3
8
  * The UserRecord passed to Cloud Functions is the same UserRecord that is returned by the Firebase Admin
4
9
  * SDK.
@@ -16,10 +21,7 @@ export declare class UserRecordMetadata implements firebase.auth.UserMetadata {
16
21
  lastSignInTime: string;
17
22
  constructor(creationTime: string, lastSignInTime: string);
18
23
  /** Returns a plain JavaScript object with the properties of UserRecordMetadata. */
19
- toJSON(): {
20
- creationTime: string;
21
- lastSignInTime: string;
22
- };
24
+ toJSON(): AuthUserMetadata;
23
25
  }
24
26
  /**
25
27
  * Helper function that creates a UserRecord Class from data sent over the wire.
@@ -27,3 +29,190 @@ export declare class UserRecordMetadata implements firebase.auth.UserMetadata {
27
29
  * @returns an instance of UserRecord with correct toJSON functions
28
30
  */
29
31
  export declare function userRecordConstructor(wireData: Object): UserRecord;
32
+ /**
33
+ * User info that is part of the AuthUserRecord
34
+ */
35
+ export interface AuthUserInfo {
36
+ /**
37
+ * The user identifier for the linked provider.
38
+ */
39
+ uid: string;
40
+ /**
41
+ * The display name for the linked provider.
42
+ */
43
+ displayName: string;
44
+ /**
45
+ * The email for the linked provider.
46
+ */
47
+ email: string;
48
+ /**
49
+ * The photo URL for the linked provider.
50
+ */
51
+ photoURL: string;
52
+ /**
53
+ * The linked provider ID (for example, "google.com" for the Google provider).
54
+ */
55
+ providerId: string;
56
+ /**
57
+ * The phone number for the linked provider.
58
+ */
59
+ phoneNumber: string;
60
+ }
61
+ /**
62
+ * Additional metadata about the user.
63
+ */
64
+ export interface AuthUserMetadata {
65
+ /**
66
+ * The date the user was created, formatted as a UTC string.
67
+ */
68
+ creationTime: string;
69
+ /**
70
+ * The date the user last signed in, formatted as a UTC string.
71
+ */
72
+ lastSignInTime: string;
73
+ }
74
+ /**
75
+ * Interface representing the common properties of a user-enrolled second factor.
76
+ */
77
+ export interface AuthMultiFactorInfo {
78
+ /**
79
+ * The ID of the enrolled second factor. This ID is unique to the user.
80
+ */
81
+ uid: string;
82
+ /**
83
+ * The optional display name of the enrolled second factor.
84
+ */
85
+ displayName?: string;
86
+ /**
87
+ * The type identifier of the second factor. For SMS second factors, this is `phone`.
88
+ */
89
+ factorId: string;
90
+ /**
91
+ * The optional date the second factor was enrolled, formatted as a UTC string.
92
+ */
93
+ enrollmentTime?: string;
94
+ /**
95
+ * The phone number associated with a phone second factor.
96
+ */
97
+ phoneNumber?: string;
98
+ }
99
+ /**
100
+ * The multi-factor related properties for the current user, if available.
101
+ */
102
+ export interface AuthMultiFactorSettings {
103
+ /**
104
+ * List of second factors enrolled with the current user.
105
+ */
106
+ enrolledFactors: AuthMultiFactorInfo[];
107
+ }
108
+ /**
109
+ * The UserRecord passed to auth blocking Cloud Functions from the identity platform.
110
+ */
111
+ export interface AuthUserRecord {
112
+ /**
113
+ * The user's `uid`.
114
+ */
115
+ uid: string;
116
+ /**
117
+ * The user's primary email, if set.
118
+ */
119
+ email?: string;
120
+ /**
121
+ * Whether or not the user's primary email is verified.
122
+ */
123
+ emailVerified: boolean;
124
+ /**
125
+ * The user's display name.
126
+ */
127
+ displayName?: string;
128
+ /**
129
+ * The user's photo URL.
130
+ */
131
+ photoURL?: string;
132
+ /**
133
+ * The user's primary phone number, if set.
134
+ */
135
+ phoneNumber?: string;
136
+ /**
137
+ * Whether or not the user is disabled: `true` for disabled; `false` for
138
+ * enabled.
139
+ */
140
+ disabled: boolean;
141
+ /**
142
+ * Additional metadata about the user.
143
+ */
144
+ metadata: AuthUserMetadata;
145
+ /**
146
+ * An array of providers (for example, Google, Facebook) linked to the user.
147
+ */
148
+ providerData: AuthUserInfo[];
149
+ /**
150
+ * The user's hashed password (base64-encoded).
151
+ */
152
+ passwordHash?: string;
153
+ /**
154
+ * The user's password salt (base64-encoded).
155
+ */
156
+ passwordSalt?: string;
157
+ /**
158
+ * The user's custom claims object if available, typically used to define
159
+ * user roles and propagated to an authenticated user's ID token.
160
+ */
161
+ customClaims?: Record<string, any>;
162
+ /**
163
+ * The ID of the tenant the user belongs to, if available.
164
+ */
165
+ tenantId?: string | null;
166
+ /**
167
+ * The date the user's tokens are valid after, formatted as a UTC string.
168
+ */
169
+ tokensValidAfterTime?: string;
170
+ /**
171
+ * The multi-factor related properties for the current user, if available.
172
+ */
173
+ multiFactor?: AuthMultiFactorSettings;
174
+ }
175
+ /** The additional user info component of the auth event context */
176
+ export interface AdditionalUserInfo {
177
+ providerId: string;
178
+ profile?: any;
179
+ username?: string;
180
+ isNewUser: boolean;
181
+ }
182
+ /** The credential component of the auth event context */
183
+ export interface Credential {
184
+ claims?: {
185
+ [key: string]: any;
186
+ };
187
+ idToken?: string;
188
+ accessToken?: string;
189
+ refreshToken?: string;
190
+ expirationTime?: string;
191
+ secret?: string;
192
+ providerId: string;
193
+ signInMethod: string;
194
+ }
195
+ /** Defines the auth event context for blocking events */
196
+ export interface AuthEventContext extends EventContext {
197
+ locale?: string;
198
+ ipAddress: string;
199
+ userAgent: string;
200
+ additionalUserInfo?: AdditionalUserInfo;
201
+ credential?: Credential;
202
+ }
203
+ /** Defines the auth event for v2 blocking events */
204
+ export interface AuthBlockingEvent extends AuthEventContext {
205
+ data: AuthUserRecord;
206
+ }
207
+ /** The handler response type for beforeCreate blocking events */
208
+ export interface BeforeCreateResponse {
209
+ displayName?: string;
210
+ disabled?: boolean;
211
+ emailVerified?: boolean;
212
+ photoURL?: string;
213
+ customClaims?: object;
214
+ }
215
+ /** The handler response type for beforeSignIn blocking events */
216
+ export interface BeforeSignInResponse extends BeforeCreateResponse {
217
+ sessionClaims?: object;
218
+ }