firebase-functions 3.15.5 → 3.17.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.
- package/lib/bin/firebase-functions.d.ts +2 -0
- package/lib/bin/firebase-functions.js +48 -0
- package/lib/cloud-functions.d.ts +14 -8
- package/lib/cloud-functions.js +61 -1
- package/lib/common/debug.d.ts +1 -0
- package/lib/common/debug.js +54 -0
- package/lib/common/encoding.js +6 -0
- package/lib/common/manifest.d.ts +1 -0
- package/lib/common/manifest.js +2 -0
- package/lib/common/providers/https.d.ts +92 -47
- package/lib/common/providers/https.js +171 -51
- package/lib/common/providers/identity.d.ts +29 -0
- package/lib/common/providers/identity.js +96 -0
- package/lib/function-builder.d.ts +7 -1
- package/lib/function-builder.js +8 -0
- package/lib/function-configuration.d.ts +1 -0
- package/lib/handler-builder.d.ts +19 -15
- package/lib/handler-builder.js +32 -15
- package/lib/providers/auth.d.ts +2 -21
- package/lib/providers/auth.js +5 -66
- package/lib/providers/database.js +2 -1
- package/lib/providers/https.d.ts +44 -2
- package/lib/providers/https.js +65 -2
- package/lib/runtime/loader.d.ts +1 -0
- package/lib/runtime/loader.js +101 -0
- package/lib/runtime/manifest.d.ts +1 -0
- package/lib/runtime/manifest.js +2 -0
- package/lib/v2/core.d.ts +10 -3
- package/lib/v2/index.d.ts +3 -1
- package/lib/v2/index.js +5 -1
- package/lib/v2/options.d.ts +1 -1
- package/lib/v2/options.js +47 -9
- package/lib/v2/params/types.d.ts +2 -1
- package/lib/v2/params/types.js +2 -0
- package/lib/v2/providers/alerts/alerts.d.ts +36 -0
- package/lib/v2/providers/alerts/alerts.js +72 -0
- package/lib/v2/providers/alerts/appDistribution.d.ts +35 -0
- package/lib/v2/providers/alerts/appDistribution.js +39 -0
- package/lib/v2/providers/alerts/billing.d.ts +38 -0
- package/lib/v2/providers/alerts/billing.js +30 -0
- package/lib/v2/providers/alerts/crashlytics.d.ts +123 -0
- package/lib/v2/providers/alerts/crashlytics.js +74 -0
- package/lib/v2/providers/alerts/index.d.ts +5 -0
- package/lib/v2/providers/alerts/index.js +20 -0
- package/lib/v2/providers/https.d.ts +24 -4
- package/lib/v2/providers/https.js +72 -3
- package/lib/v2/providers/pubsub.d.ts +1 -1
- package/lib/v2/providers/pubsub.js +19 -4
- package/lib/v2/providers/storage.d.ts +170 -0
- package/lib/v2/providers/storage.js +137 -0
- package/package.json +34 -7
|
@@ -21,12 +21,14 @@
|
|
|
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.onCallHandler = exports.decode = exports.encode = exports.HttpsError = void 0;
|
|
24
|
+
exports.onDispatchHandler = exports.onCallHandler = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.decode = exports.encode = 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");
|
|
31
|
+
const JWT_REGEX = /^[a-zA-Z0-9\-_=]+?\.[a-zA-Z0-9\-_=]+?\.([a-zA-Z0-9\-_=]+)?$/;
|
|
30
32
|
/**
|
|
31
33
|
* Standard error codes and HTTP statuses for different ways a request can fail,
|
|
32
34
|
* as defined by:
|
|
@@ -148,7 +150,7 @@ function encode(data) {
|
|
|
148
150
|
if (Array.isArray(data)) {
|
|
149
151
|
return data.map(encode);
|
|
150
152
|
}
|
|
151
|
-
if (typeof data === 'object') {
|
|
153
|
+
if (typeof data === 'object' || typeof data === 'function') {
|
|
152
154
|
// Sadly we don't have Object.fromEntries in Node 10, so we can't use a single
|
|
153
155
|
// list comprehension
|
|
154
156
|
const obj = {};
|
|
@@ -206,6 +208,53 @@ function decode(data) {
|
|
|
206
208
|
return data;
|
|
207
209
|
}
|
|
208
210
|
exports.decode = decode;
|
|
211
|
+
function unsafeDecodeToken(token) {
|
|
212
|
+
if (!JWT_REGEX.test(token)) {
|
|
213
|
+
return {};
|
|
214
|
+
}
|
|
215
|
+
const components = token
|
|
216
|
+
.split('.')
|
|
217
|
+
.map((s) => Buffer.from(s, 'base64').toString());
|
|
218
|
+
let payload = components[1];
|
|
219
|
+
if (typeof payload === 'string') {
|
|
220
|
+
try {
|
|
221
|
+
const obj = JSON.parse(payload);
|
|
222
|
+
if (typeof obj === 'object') {
|
|
223
|
+
payload = obj;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) { }
|
|
227
|
+
}
|
|
228
|
+
return payload;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Decode, but not verify, a Auth ID token.
|
|
232
|
+
*
|
|
233
|
+
* Do not use in production. Token should always be verified using the Admin SDK.
|
|
234
|
+
*
|
|
235
|
+
* This is exposed only for testing.
|
|
236
|
+
*/
|
|
237
|
+
/** @internal */
|
|
238
|
+
function unsafeDecodeIdToken(token) {
|
|
239
|
+
const decoded = unsafeDecodeToken(token);
|
|
240
|
+
decoded.uid = decoded.sub;
|
|
241
|
+
return decoded;
|
|
242
|
+
}
|
|
243
|
+
exports.unsafeDecodeIdToken = unsafeDecodeIdToken;
|
|
244
|
+
/**
|
|
245
|
+
* Decode, but not verify, an App Check token.
|
|
246
|
+
*
|
|
247
|
+
* Do not use in production. Token should always be verified using the Admin SDK.
|
|
248
|
+
*
|
|
249
|
+
* This is exposed only for testing.
|
|
250
|
+
*/
|
|
251
|
+
/** @internal */
|
|
252
|
+
function unsafeDecodeAppCheckToken(token) {
|
|
253
|
+
const decoded = unsafeDecodeToken(token);
|
|
254
|
+
decoded.app_id = decoded.sub;
|
|
255
|
+
return decoded;
|
|
256
|
+
}
|
|
257
|
+
exports.unsafeDecodeAppCheckToken = unsafeDecodeAppCheckToken;
|
|
209
258
|
/**
|
|
210
259
|
* Check and verify tokens included in the requests. Once verified, tokens
|
|
211
260
|
* are injected into the callable context.
|
|
@@ -214,53 +263,20 @@ exports.decode = decode;
|
|
|
214
263
|
* @param {CallableContext} ctx - Context to be sent to callable function handler.
|
|
215
264
|
* @return {CallableTokenStatus} Status of the token verifications.
|
|
216
265
|
*/
|
|
217
|
-
/** @
|
|
266
|
+
/** @internal */
|
|
218
267
|
async function checkTokens(req, ctx) {
|
|
219
268
|
const verifications = {
|
|
220
|
-
app: '
|
|
221
|
-
auth: '
|
|
269
|
+
app: 'INVALID',
|
|
270
|
+
auth: 'INVALID',
|
|
222
271
|
};
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
.admin.appCheck()
|
|
232
|
-
.verifyToken(appCheck);
|
|
233
|
-
ctx.app = {
|
|
234
|
-
appId: appCheckToken.appId,
|
|
235
|
-
token: appCheckToken.token,
|
|
236
|
-
};
|
|
237
|
-
verifications.app = 'VALID';
|
|
238
|
-
}
|
|
239
|
-
catch (err) {
|
|
240
|
-
logger.warn('Failed to validate AppCheck token.', err);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const authorization = req.header('Authorization');
|
|
244
|
-
if (authorization) {
|
|
245
|
-
verifications.auth = 'INVALID';
|
|
246
|
-
const match = authorization.match(/^Bearer (.*)$/);
|
|
247
|
-
if (match) {
|
|
248
|
-
const idToken = match[1];
|
|
249
|
-
try {
|
|
250
|
-
const authToken = await (0, apps_1.apps)()
|
|
251
|
-
.admin.auth()
|
|
252
|
-
.verifyIdToken(idToken);
|
|
253
|
-
verifications.auth = 'VALID';
|
|
254
|
-
ctx.auth = {
|
|
255
|
-
uid: authToken.uid,
|
|
256
|
-
token: authToken,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
catch (err) {
|
|
260
|
-
logger.warn('Failed to validate auth token.', err);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
272
|
+
await Promise.all([
|
|
273
|
+
Promise.resolve().then(async () => {
|
|
274
|
+
verifications.auth = await checkAuthToken(req, ctx);
|
|
275
|
+
}),
|
|
276
|
+
Promise.resolve().then(async () => {
|
|
277
|
+
verifications.app = await checkAppCheckToken(req, ctx);
|
|
278
|
+
}),
|
|
279
|
+
]);
|
|
264
280
|
const logPayload = {
|
|
265
281
|
verifications,
|
|
266
282
|
'logging.googleapis.com/labels': {
|
|
@@ -282,13 +298,72 @@ async function checkTokens(req, ctx) {
|
|
|
282
298
|
}
|
|
283
299
|
return verifications;
|
|
284
300
|
}
|
|
285
|
-
/** @
|
|
301
|
+
/** @interanl */
|
|
302
|
+
async function checkAuthToken(req, ctx) {
|
|
303
|
+
const authorization = req.header('Authorization');
|
|
304
|
+
if (!authorization) {
|
|
305
|
+
return 'MISSING';
|
|
306
|
+
}
|
|
307
|
+
const match = authorization.match(/^Bearer (.*)$/);
|
|
308
|
+
if (match) {
|
|
309
|
+
const idToken = match[1];
|
|
310
|
+
try {
|
|
311
|
+
let authToken;
|
|
312
|
+
if ((0, debug_1.isDebugFeatureEnabled)('skipTokenVerification')) {
|
|
313
|
+
authToken = unsafeDecodeIdToken(idToken);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
authToken = await (0, apps_1.apps)()
|
|
317
|
+
.admin.auth()
|
|
318
|
+
.verifyIdToken(idToken);
|
|
319
|
+
}
|
|
320
|
+
ctx.auth = {
|
|
321
|
+
uid: authToken.uid,
|
|
322
|
+
token: authToken,
|
|
323
|
+
};
|
|
324
|
+
return 'VALID';
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
logger.warn('Failed to validate auth token.', err);
|
|
328
|
+
return 'INVALID';
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/** @internal */
|
|
333
|
+
async function checkAppCheckToken(req, ctx) {
|
|
334
|
+
const appCheck = req.header('X-Firebase-AppCheck');
|
|
335
|
+
if (!appCheck) {
|
|
336
|
+
return 'MISSING';
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
if (!(0, apps_1.apps)().admin.appCheck) {
|
|
340
|
+
throw new Error('Cannot validate AppCheck token. Please update Firebase Admin SDK to >= v9.8.0');
|
|
341
|
+
}
|
|
342
|
+
let appCheckData;
|
|
343
|
+
if ((0, debug_1.isDebugFeatureEnabled)('skipTokenVerification')) {
|
|
344
|
+
const decodedToken = unsafeDecodeAppCheckToken(appCheck);
|
|
345
|
+
appCheckData = { appId: decodedToken.app_id, token: decodedToken };
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
appCheckData = await (0, apps_1.apps)()
|
|
349
|
+
.admin.appCheck()
|
|
350
|
+
.verifyToken(appCheck);
|
|
351
|
+
}
|
|
352
|
+
ctx.app = appCheckData;
|
|
353
|
+
return 'VALID';
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
logger.warn('Failed to validate AppCheck token.', err);
|
|
357
|
+
return 'INVALID';
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/** @internal */
|
|
286
361
|
function onCallHandler(options, handler) {
|
|
287
|
-
const wrapped = wrapOnCallHandler(handler);
|
|
362
|
+
const wrapped = wrapOnCallHandler(options, handler);
|
|
288
363
|
return (req, res) => {
|
|
289
364
|
return new Promise((resolve) => {
|
|
290
365
|
res.on('finish', resolve);
|
|
291
|
-
cors(options)(req, res, () => {
|
|
366
|
+
cors(options.cors)(req, res, () => {
|
|
292
367
|
resolve(wrapped(req, res));
|
|
293
368
|
});
|
|
294
369
|
});
|
|
@@ -296,7 +371,7 @@ function onCallHandler(options, handler) {
|
|
|
296
371
|
}
|
|
297
372
|
exports.onCallHandler = onCallHandler;
|
|
298
373
|
/** @internal */
|
|
299
|
-
function wrapOnCallHandler(handler) {
|
|
374
|
+
function wrapOnCallHandler(options, handler) {
|
|
300
375
|
return async (req, res) => {
|
|
301
376
|
try {
|
|
302
377
|
if (!isValidRequest(req)) {
|
|
@@ -305,7 +380,10 @@ function wrapOnCallHandler(handler) {
|
|
|
305
380
|
}
|
|
306
381
|
const context = { rawRequest: req };
|
|
307
382
|
const tokenStatus = await checkTokens(req, context);
|
|
308
|
-
if (tokenStatus.
|
|
383
|
+
if (tokenStatus.auth === 'INVALID') {
|
|
384
|
+
throw new HttpsError('unauthenticated', 'Unauthenticated');
|
|
385
|
+
}
|
|
386
|
+
if (tokenStatus.app === 'INVALID' && !options.allowInvalidAppCheckToken) {
|
|
309
387
|
throw new HttpsError('unauthenticated', 'Unauthenticated');
|
|
310
388
|
}
|
|
311
389
|
const instanceId = req.header('Firebase-Instance-ID-Token');
|
|
@@ -348,3 +426,45 @@ function wrapOnCallHandler(handler) {
|
|
|
348
426
|
}
|
|
349
427
|
};
|
|
350
428
|
}
|
|
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;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as firebase from 'firebase-admin';
|
|
2
|
+
/**
|
|
3
|
+
* The UserRecord passed to Cloud Functions is the same UserRecord that is returned by the Firebase Admin
|
|
4
|
+
* SDK.
|
|
5
|
+
*/
|
|
6
|
+
export declare type UserRecord = firebase.auth.UserRecord;
|
|
7
|
+
/**
|
|
8
|
+
* UserInfo that is part of the UserRecord
|
|
9
|
+
*/
|
|
10
|
+
export declare type UserInfo = firebase.auth.UserInfo;
|
|
11
|
+
/**
|
|
12
|
+
* Helper class to create the user metadata in a UserRecord object
|
|
13
|
+
*/
|
|
14
|
+
export declare class UserRecordMetadata implements firebase.auth.UserMetadata {
|
|
15
|
+
creationTime: string;
|
|
16
|
+
lastSignInTime: string;
|
|
17
|
+
constructor(creationTime: string, lastSignInTime: string);
|
|
18
|
+
/** Returns a plain JavaScript object with the properties of UserRecordMetadata. */
|
|
19
|
+
toJSON(): {
|
|
20
|
+
creationTime: string;
|
|
21
|
+
lastSignInTime: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Helper function that creates a UserRecord Class from data sent over the wire.
|
|
26
|
+
* @param wireData data sent over the wire
|
|
27
|
+
* @returns an instance of UserRecord with correct toJSON functions
|
|
28
|
+
*/
|
|
29
|
+
export declare function userRecordConstructor(wireData: Object): UserRecord;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The MIT License (MIT)
|
|
3
|
+
//
|
|
4
|
+
// Copyright (c) 2022 Firebase
|
|
5
|
+
//
|
|
6
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
// in the Software without restriction, including without limitation the rights
|
|
9
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
// furnished to do so, subject to the following conditions:
|
|
12
|
+
//
|
|
13
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
// copies or substantial portions of the Software.
|
|
15
|
+
//
|
|
16
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
// SOFTWARE.
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.userRecordConstructor = exports.UserRecordMetadata = void 0;
|
|
25
|
+
const _ = require("lodash");
|
|
26
|
+
/**
|
|
27
|
+
* Helper class to create the user metadata in a UserRecord object
|
|
28
|
+
*/
|
|
29
|
+
class UserRecordMetadata {
|
|
30
|
+
constructor(creationTime, lastSignInTime) {
|
|
31
|
+
this.creationTime = creationTime;
|
|
32
|
+
this.lastSignInTime = lastSignInTime;
|
|
33
|
+
}
|
|
34
|
+
/** Returns a plain JavaScript object with the properties of UserRecordMetadata. */
|
|
35
|
+
toJSON() {
|
|
36
|
+
return {
|
|
37
|
+
creationTime: this.creationTime,
|
|
38
|
+
lastSignInTime: this.lastSignInTime,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.UserRecordMetadata = UserRecordMetadata;
|
|
43
|
+
/**
|
|
44
|
+
* Helper function that creates a UserRecord Class from data sent over the wire.
|
|
45
|
+
* @param wireData data sent over the wire
|
|
46
|
+
* @returns an instance of UserRecord with correct toJSON functions
|
|
47
|
+
*/
|
|
48
|
+
function userRecordConstructor(wireData) {
|
|
49
|
+
// Falsey values from the wire format proto get lost when converted to JSON, this adds them back.
|
|
50
|
+
const falseyValues = {
|
|
51
|
+
email: null,
|
|
52
|
+
emailVerified: false,
|
|
53
|
+
displayName: null,
|
|
54
|
+
photoURL: null,
|
|
55
|
+
phoneNumber: null,
|
|
56
|
+
disabled: false,
|
|
57
|
+
providerData: [],
|
|
58
|
+
customClaims: {},
|
|
59
|
+
passwordSalt: null,
|
|
60
|
+
passwordHash: null,
|
|
61
|
+
tokensValidAfterTime: null,
|
|
62
|
+
};
|
|
63
|
+
const record = _.assign({}, falseyValues, wireData);
|
|
64
|
+
const meta = _.get(record, 'metadata');
|
|
65
|
+
if (meta) {
|
|
66
|
+
_.set(record, 'metadata', new UserRecordMetadata(meta.createdAt || meta.creationTime, meta.lastSignedInAt || meta.lastSignInTime));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
_.set(record, 'metadata', new UserRecordMetadata(null, null));
|
|
70
|
+
}
|
|
71
|
+
_.forEach(record.providerData, (entry) => {
|
|
72
|
+
_.set(entry, 'toJSON', () => {
|
|
73
|
+
return entry;
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
_.set(record, 'toJSON', () => {
|
|
77
|
+
const json = _.pick(record, [
|
|
78
|
+
'uid',
|
|
79
|
+
'email',
|
|
80
|
+
'emailVerified',
|
|
81
|
+
'displayName',
|
|
82
|
+
'photoURL',
|
|
83
|
+
'phoneNumber',
|
|
84
|
+
'disabled',
|
|
85
|
+
'passwordHash',
|
|
86
|
+
'passwordSalt',
|
|
87
|
+
'tokensValidAfterTime',
|
|
88
|
+
]);
|
|
89
|
+
json.metadata = _.get(record, 'metadata').toJSON();
|
|
90
|
+
json.customClaims = _.cloneDeep(record.customClaims);
|
|
91
|
+
json.providerData = _.map(record.providerData, (entry) => entry.toJSON());
|
|
92
|
+
return json;
|
|
93
|
+
});
|
|
94
|
+
return record;
|
|
95
|
+
}
|
|
96
|
+
exports.userRecordConstructor = userRecordConstructor;
|
|
@@ -77,7 +77,13 @@ export declare class FunctionBuilder {
|
|
|
77
77
|
* Declares a callable method for clients to call using a Firebase SDK.
|
|
78
78
|
* @param handler A method that takes a data and context and returns a value.
|
|
79
79
|
*/
|
|
80
|
-
onCall: (handler: (data: any, context: https.CallableContext) => any | Promise<any>) => import("./cloud-functions").TriggerAnnotated & ((req: express.Request<import("express-serve-static-core").ParamsDictionary>, resp: express.Response<any>) => void | Promise<void>) & import("./cloud-functions").Runnable<any>;
|
|
80
|
+
onCall: (handler: (data: any, context: https.CallableContext) => any | Promise<any>) => import("./cloud-functions").TriggerAnnotated & import("./cloud-functions").EndpointAnnotated & ((req: express.Request<import("express-serve-static-core").ParamsDictionary>, resp: express.Response<any>) => void | Promise<void>) & import("./cloud-functions").Runnable<any>;
|
|
81
|
+
/**
|
|
82
|
+
* Declares a task queue function for clients to call using a Firebase Admin SDK.
|
|
83
|
+
* @param options Configurations for the task queue function.
|
|
84
|
+
*/
|
|
85
|
+
/** @hidden */
|
|
86
|
+
taskQueue: (options?: https.TaskQueueOptions) => https.TaskQueueBuilder;
|
|
81
87
|
};
|
|
82
88
|
get database(): {
|
|
83
89
|
/**
|
package/lib/function-builder.js
CHANGED
|
@@ -231,6 +231,14 @@ class FunctionBuilder {
|
|
|
231
231
|
* @param handler A method that takes a data and context and returns a value.
|
|
232
232
|
*/
|
|
233
233
|
onCall: (handler) => https._onCallWithOptions(handler, this.options),
|
|
234
|
+
/**
|
|
235
|
+
* Declares a task queue function for clients to call using a Firebase Admin SDK.
|
|
236
|
+
* @param options Configurations for the task queue function.
|
|
237
|
+
*/
|
|
238
|
+
/** @hidden */
|
|
239
|
+
taskQueue: (options) => {
|
|
240
|
+
return new https.TaskQueueBuilder(options, this.options);
|
|
241
|
+
},
|
|
234
242
|
};
|
|
235
243
|
}
|
|
236
244
|
get database() {
|
|
@@ -98,6 +98,7 @@ export interface RuntimeOptions {
|
|
|
98
98
|
* Invoker to set access control on https functions.
|
|
99
99
|
*/
|
|
100
100
|
invoker?: 'public' | 'private' | string | string[];
|
|
101
|
+
allowInvalidAppCheckToken?: boolean;
|
|
101
102
|
}
|
|
102
103
|
export interface DeploymentOptions extends RuntimeOptions {
|
|
103
104
|
regions?: Array<typeof SUPPORTED_REGIONS[number] | string>;
|
package/lib/handler-builder.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare class HandlerBuilder {
|
|
|
22
22
|
constructor();
|
|
23
23
|
/**
|
|
24
24
|
* Create a handler for HTTPS events.
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
* `onRequest` handles an HTTPS request and has the same signature as an Express app.
|
|
27
27
|
*
|
|
28
28
|
* @example
|
|
@@ -40,6 +40,10 @@ export declare class HandlerBuilder {
|
|
|
40
40
|
get https(): {
|
|
41
41
|
onRequest: (handler: (req: express.Request, resp: express.Response) => void) => HttpsFunction;
|
|
42
42
|
onCall: (handler: (data: any, context: https.CallableContext) => any | Promise<any>) => HttpsFunction;
|
|
43
|
+
/** @hidden */
|
|
44
|
+
readonly taskQueue: {
|
|
45
|
+
onEnqueue(handler: (data: any, context: https.TaskContext) => void | Promise<void>): https.TaskQueueFunction;
|
|
46
|
+
};
|
|
43
47
|
};
|
|
44
48
|
/**
|
|
45
49
|
* Create a handler for Firebase Realtime Database events.
|
|
@@ -57,7 +61,7 @@ export declare class HandlerBuilder {
|
|
|
57
61
|
* ```javascript
|
|
58
62
|
* exports.myFunction = functions.handler.database.ref.onUpdate((change, context) => { ... })
|
|
59
63
|
* ```
|
|
60
|
-
|
|
64
|
+
|
|
61
65
|
* `ref.onDelete` handles the deletion of existing data.
|
|
62
66
|
*
|
|
63
67
|
* @example
|
|
@@ -88,14 +92,14 @@ export declare class HandlerBuilder {
|
|
|
88
92
|
* ```javascript
|
|
89
93
|
* exports.myFunction = functions.handler.firestore.document.onCreate((snap, context) => { ... })
|
|
90
94
|
* ```
|
|
91
|
-
|
|
95
|
+
|
|
92
96
|
* `document.onUpdate` handles updates to existing documents.
|
|
93
97
|
*
|
|
94
98
|
* @example
|
|
95
99
|
* ```javascript
|
|
96
100
|
* exports.myFunction = functions.handler.firestore.document.onUpdate((change, context) => { ... })
|
|
97
101
|
* ```
|
|
98
|
-
|
|
102
|
+
|
|
99
103
|
* `document.onDelete` handles the deletion of existing documents.
|
|
100
104
|
*
|
|
101
105
|
* @example
|
|
@@ -103,7 +107,7 @@ export declare class HandlerBuilder {
|
|
|
103
107
|
* exports.myFunction = functions.handler.firestore.document.onDelete((snap, context) =>
|
|
104
108
|
* { ... })
|
|
105
109
|
* ```
|
|
106
|
-
|
|
110
|
+
|
|
107
111
|
* `document.onWrite` handles the creation, update, or deletion of documents.
|
|
108
112
|
*
|
|
109
113
|
* @example
|
|
@@ -123,7 +127,7 @@ export declare class HandlerBuilder {
|
|
|
123
127
|
* Create a handler for Firebase Remote Config events.
|
|
124
128
|
|
|
125
129
|
* `remoteConfig.onUpdate` handles events that update a Remote Config template.
|
|
126
|
-
|
|
130
|
+
|
|
127
131
|
* @example
|
|
128
132
|
* ```javascript
|
|
129
133
|
* exports.myFunction = functions.handler.remoteConfig.onUpdate() => { ... })
|
|
@@ -134,9 +138,9 @@ export declare class HandlerBuilder {
|
|
|
134
138
|
};
|
|
135
139
|
/**
|
|
136
140
|
* Create a handler for Google Analytics events.
|
|
137
|
-
|
|
141
|
+
|
|
138
142
|
* `event.onLog` handles the logging of Analytics conversion events.
|
|
139
|
-
|
|
143
|
+
|
|
140
144
|
* @example
|
|
141
145
|
* ```javascript
|
|
142
146
|
* exports.myFunction = functions.handler.analytics.event.onLog((event) => { ... })
|
|
@@ -154,14 +158,14 @@ export declare class HandlerBuilder {
|
|
|
154
158
|
* ```javascript
|
|
155
159
|
* exports.myFunction = functions.handler.storage.object.onArchive((object) => { ... })
|
|
156
160
|
* ```
|
|
157
|
-
|
|
161
|
+
|
|
158
162
|
* `object.onDelete` handles the deletion of Storage objects.
|
|
159
163
|
*
|
|
160
164
|
* @example
|
|
161
165
|
* ```javascript
|
|
162
166
|
* exports.myFunction = functions.handler.storage.object.onDelete((object) => { ... })
|
|
163
167
|
* ```
|
|
164
|
-
|
|
168
|
+
|
|
165
169
|
* `object.onFinalize` handles the creation of Storage objects.
|
|
166
170
|
*
|
|
167
171
|
* @example
|
|
@@ -169,7 +173,7 @@ export declare class HandlerBuilder {
|
|
|
169
173
|
* exports.myFunction = functions.handler.storage.object.onFinalize((object) =>
|
|
170
174
|
* { ... })
|
|
171
175
|
* ```
|
|
172
|
-
|
|
176
|
+
|
|
173
177
|
* `object.onMetadataUpdate` handles changes to the metadata of existing Storage objects.
|
|
174
178
|
*
|
|
175
179
|
* @example
|
|
@@ -191,7 +195,7 @@ export declare class HandlerBuilder {
|
|
|
191
195
|
* ```javascript
|
|
192
196
|
* exports.myFunction = functions.handler.pubsub.topic.onPublish((message) => { ... })
|
|
193
197
|
* ```
|
|
194
|
-
|
|
198
|
+
|
|
195
199
|
* `schedule.onPublish` handles messages published to a Pub/Sub topic on a schedule.
|
|
196
200
|
*
|
|
197
201
|
* @example
|
|
@@ -212,14 +216,14 @@ export declare class HandlerBuilder {
|
|
|
212
216
|
* ```javascript
|
|
213
217
|
* exports.myFunction = functions.handler.auth.user.onCreate((user) => { ... })
|
|
214
218
|
* ```
|
|
215
|
-
|
|
219
|
+
|
|
216
220
|
* `user.onDelete` handles the deletion of users.
|
|
217
221
|
*
|
|
218
222
|
* @example
|
|
219
223
|
* ```javascript
|
|
220
224
|
* exports.myFunction = functions.handler.auth.user.onDelete((user => { ... })
|
|
221
225
|
* ```
|
|
222
|
-
|
|
226
|
+
|
|
223
227
|
*/
|
|
224
228
|
get auth(): {
|
|
225
229
|
readonly user: auth.UserBuilder;
|
|
@@ -228,7 +232,7 @@ export declare class HandlerBuilder {
|
|
|
228
232
|
* Create a handler for Firebase Test Lab events.
|
|
229
233
|
|
|
230
234
|
* `testMatrix.onComplete` handles the completion of a test matrix.
|
|
231
|
-
|
|
235
|
+
|
|
232
236
|
* @example
|
|
233
237
|
* ```javascript
|
|
234
238
|
* exports.myFunction = functions.handler.testLab.testMatrix.onComplete((testMatrix) => { ... })
|