firebase-tools 9.18.0 → 9.22.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/CHANGELOG.md +3 -6
- package/lib/api.js +3 -0
- package/lib/apiv2.js +8 -5
- package/lib/command.js +1 -1
- package/lib/commands/crashlytics-symbols-upload.js +146 -0
- package/lib/commands/deploy.js +9 -1
- package/lib/commands/ext-configure.js +9 -2
- package/lib/commands/ext-dev-deprecate.js +63 -0
- package/lib/commands/ext-dev-extension-delete.js +2 -1
- package/lib/commands/ext-dev-publish.js +10 -4
- package/lib/commands/ext-dev-undeprecate.js +56 -0
- package/lib/commands/ext-dev-unpublish.js +12 -4
- package/lib/commands/ext-export.js +44 -0
- package/lib/commands/ext-install.js +50 -13
- package/lib/commands/ext-uninstall.js +6 -0
- package/lib/commands/ext-update.js +60 -18
- package/lib/commands/functions-config-export.js +115 -0
- package/lib/commands/functions-delete.js +47 -25
- package/lib/commands/functions-list.js +12 -12
- package/lib/commands/index.js +9 -0
- package/lib/commands/init.js +3 -0
- package/lib/config.js +3 -2
- package/lib/deploy/extensions/args.js +2 -0
- package/lib/deploy/extensions/deploy.js +49 -0
- package/lib/deploy/extensions/deploymentSummary.js +52 -0
- package/lib/deploy/extensions/errors.js +31 -0
- package/lib/deploy/extensions/index.js +8 -0
- package/lib/deploy/extensions/planner.js +95 -0
- package/lib/deploy/extensions/prepare.js +103 -0
- package/lib/deploy/extensions/release.js +43 -0
- package/lib/deploy/extensions/secrets.js +150 -0
- package/lib/deploy/extensions/tasks.js +98 -0
- package/lib/deploy/extensions/validate.js +17 -0
- package/lib/deploy/functions/backend.js +93 -115
- package/lib/deploy/functions/checkIam.js +8 -8
- package/lib/deploy/functions/containerCleaner.js +82 -22
- package/lib/deploy/functions/deploy.js +4 -10
- package/lib/deploy/functions/functionsDeployHelper.js +3 -68
- package/lib/deploy/functions/prepare.js +62 -27
- package/lib/deploy/functions/pricing.js +17 -17
- package/lib/deploy/functions/prompts.js +22 -21
- package/lib/deploy/functions/release/executor.js +39 -0
- package/lib/deploy/functions/release/fabricator.js +422 -0
- package/lib/deploy/functions/release/index.js +73 -0
- package/lib/deploy/functions/release/planner.js +162 -0
- package/lib/deploy/functions/release/reporter.js +165 -0
- package/lib/deploy/functions/release/sourceTokenScraper.js +28 -0
- package/lib/deploy/functions/release/timer.js +14 -0
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +129 -126
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +41 -45
- package/lib/deploy/functions/triggerRegionHelper.js +40 -0
- package/lib/deploy/functions/validate.js +1 -24
- package/lib/deploy/index.js +1 -0
- package/lib/downloadUtils.js +37 -0
- package/lib/emulator/auth/apiSpec.js +1788 -403
- package/lib/emulator/auth/handlers.js +6 -5
- package/lib/emulator/auth/operations.js +439 -40
- package/lib/emulator/auth/server.js +32 -11
- package/lib/emulator/auth/state.js +205 -5
- package/lib/emulator/auth/widget_ui.js +2 -2
- package/lib/emulator/download.js +2 -31
- package/lib/emulator/downloadableEmulators.js +7 -7
- package/lib/emulator/emulatorLogger.js +0 -3
- package/lib/emulator/events/types.js +16 -0
- package/lib/emulator/functionsEmulator.js +120 -21
- package/lib/emulator/functionsEmulatorRuntime.js +46 -121
- package/lib/emulator/functionsEmulatorShared.js +51 -7
- package/lib/emulator/functionsEmulatorShell.js +1 -1
- package/lib/emulator/pubsubEmulator.js +61 -40
- package/lib/emulator/storage/cloudFunctions.js +37 -7
- package/lib/extensions/askUserForConsent.js +14 -1
- package/lib/extensions/askUserForParam.js +81 -4
- package/lib/extensions/billingMigrationHelper.js +1 -11
- package/lib/extensions/changelog.js +2 -1
- package/lib/extensions/checkProjectBilling.js +7 -7
- package/lib/extensions/displayExtensionInfo.js +35 -33
- package/lib/extensions/emulator/optionsHelper.js +3 -3
- package/lib/extensions/emulator/triggerHelper.js +2 -32
- package/lib/extensions/export.js +107 -0
- package/lib/extensions/extensionsApi.js +149 -97
- package/lib/extensions/extensionsHelper.js +36 -32
- package/lib/extensions/listExtensions.js +16 -11
- package/lib/extensions/paramHelper.js +73 -40
- package/lib/extensions/provisioningHelper.js +16 -3
- package/lib/extensions/refs.js +67 -0
- package/lib/extensions/secretsUtils.js +59 -0
- package/lib/extensions/updateHelper.js +33 -47
- package/lib/extensions/versionHelper.js +14 -0
- package/lib/extensions/warnings.js +33 -1
- package/lib/functional.js +64 -0
- package/lib/functions/env.js +26 -13
- package/lib/functions/runtimeConfigExport.js +137 -0
- package/lib/gcp/artifactregistry.js +16 -0
- package/lib/gcp/cloudfunctions.js +65 -35
- package/lib/gcp/cloudfunctionsv2.js +56 -43
- package/lib/gcp/cloudscheduler.js +22 -16
- package/lib/gcp/cloudtasks.js +143 -0
- package/lib/gcp/docker.js +7 -1
- package/lib/gcp/proto.js +2 -2
- package/lib/gcp/pubsub.js +1 -9
- package/lib/gcp/secretManager.js +132 -0
- package/lib/gcp/storage.js +16 -0
- package/lib/previews.js +1 -1
- package/lib/requireInteractive.js +12 -0
- package/lib/utils.js +30 -1
- package/package.json +6 -4
- package/schema/firebase-config.json +9 -0
- package/lib/deploy/functions/deploymentPlanner.js +0 -113
- package/lib/deploy/functions/deploymentTimer.js +0 -23
- package/lib/deploy/functions/errorHandler.js +0 -75
- package/lib/deploy/functions/release.js +0 -116
- package/lib/deploy/functions/tasks.js +0 -324
- package/lib/functions/listFunctions.js +0 -10
- package/lib/functionsDelete.js +0 -60
|
@@ -17,6 +17,7 @@ const lodash_1 = require("lodash");
|
|
|
17
17
|
const handlers_1 = require("./handlers");
|
|
18
18
|
const bodyParser = require("body-parser");
|
|
19
19
|
const url_1 = require("url");
|
|
20
|
+
const jsonwebtoken_1 = require("jsonwebtoken");
|
|
20
21
|
const apiSpec = apiSpec_1.default;
|
|
21
22
|
const API_SPEC_PATH = "/emulator/openapi.json";
|
|
22
23
|
const AUTH_HEADER_PREFIX = "bearer ";
|
|
@@ -70,6 +71,10 @@ async function createApp(defaultProjectId, projectStateForId = new Map()) {
|
|
|
70
71
|
const app = express();
|
|
71
72
|
app.set("json spaces", 2);
|
|
72
73
|
app.use(cors({ origin: true }));
|
|
74
|
+
app.delete("*", (req, _, next) => {
|
|
75
|
+
delete req.headers["content-type"];
|
|
76
|
+
next();
|
|
77
|
+
});
|
|
73
78
|
app.get("/", (req, res) => {
|
|
74
79
|
return res.json({
|
|
75
80
|
authEmulator: {
|
|
@@ -83,7 +88,7 @@ async function createApp(defaultProjectId, projectStateForId = new Map()) {
|
|
|
83
88
|
res.json(specWithEmulatorServer(req.protocol, req.headers.host));
|
|
84
89
|
});
|
|
85
90
|
registerLegacyRoutes(app);
|
|
86
|
-
handlers_1.registerHandlers(app, (apiKey) => getProjectStateById(getProjectIdByApiKey(apiKey)));
|
|
91
|
+
handlers_1.registerHandlers(app, (apiKey, tenantId) => getProjectStateById(getProjectIdByApiKey(apiKey), tenantId));
|
|
87
92
|
const apiKeyAuthenticator = (ctx, info) => {
|
|
88
93
|
if (info.in !== "query") {
|
|
89
94
|
throw new Error('apiKey must be defined as in: "query" in API spec.');
|
|
@@ -169,6 +174,9 @@ async function createApp(defaultProjectId, projectStateForId = new Map()) {
|
|
|
169
174
|
"google-fieldmask"() {
|
|
170
175
|
return true;
|
|
171
176
|
},
|
|
177
|
+
"google-duration"() {
|
|
178
|
+
return true;
|
|
179
|
+
},
|
|
172
180
|
uint64() {
|
|
173
181
|
return true;
|
|
174
182
|
},
|
|
@@ -234,13 +242,16 @@ async function createApp(defaultProjectId, projectStateForId = new Map()) {
|
|
|
234
242
|
apiKey;
|
|
235
243
|
return defaultProjectId;
|
|
236
244
|
}
|
|
237
|
-
function getProjectStateById(projectId) {
|
|
238
|
-
let
|
|
239
|
-
if (!
|
|
240
|
-
|
|
241
|
-
projectStateForId.set(projectId,
|
|
245
|
+
function getProjectStateById(projectId, tenantId) {
|
|
246
|
+
let agentState = projectStateForId.get(projectId);
|
|
247
|
+
if (!agentState) {
|
|
248
|
+
agentState = new state_1.AgentProjectState(projectId);
|
|
249
|
+
projectStateForId.set(projectId, agentState);
|
|
242
250
|
}
|
|
243
|
-
|
|
251
|
+
if (!tenantId) {
|
|
252
|
+
return agentState;
|
|
253
|
+
}
|
|
254
|
+
return agentState.getTenantProject(tenantId);
|
|
244
255
|
}
|
|
245
256
|
}
|
|
246
257
|
exports.createApp = createApp;
|
|
@@ -328,7 +339,7 @@ function toExegesisController(ops, getProjectStateById) {
|
|
|
328
339
|
}
|
|
329
340
|
function toExegesisOperation(operation) {
|
|
330
341
|
return (ctx) => {
|
|
331
|
-
var _a, _b, _c, _d;
|
|
342
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
332
343
|
let targetProjectId = ctx.params.path.targetProjectId || ((_a = ctx.requestBody) === null || _a === void 0 ? void 0 : _a.targetProjectId);
|
|
333
344
|
if (targetProjectId) {
|
|
334
345
|
if ((_b = ctx.api.operationObject.security) === null || _b === void 0 ? void 0 : _b.some((sec) => sec.Oauth2)) {
|
|
@@ -338,10 +349,20 @@ function toExegesisController(ops, getProjectStateById) {
|
|
|
338
349
|
else {
|
|
339
350
|
targetProjectId = ctx.user;
|
|
340
351
|
}
|
|
341
|
-
|
|
342
|
-
|
|
352
|
+
let targetTenantId = undefined;
|
|
353
|
+
if (ctx.params.path.tenantId && ((_d = ctx.requestBody) === null || _d === void 0 ? void 0 : _d.tenantId)) {
|
|
354
|
+
errors_2.assert(ctx.params.path.tenantId === ctx.requestBody.tenantId, "TENANT_ID_MISMATCH");
|
|
355
|
+
}
|
|
356
|
+
targetTenantId = ctx.params.path.tenantId || ((_e = ctx.requestBody) === null || _e === void 0 ? void 0 : _e.tenantId);
|
|
357
|
+
if ((_f = ctx.requestBody) === null || _f === void 0 ? void 0 : _f.idToken) {
|
|
358
|
+
const idToken = (_g = ctx.requestBody) === null || _g === void 0 ? void 0 : _g.idToken;
|
|
359
|
+
const decoded = jsonwebtoken_1.decode(idToken, { complete: true });
|
|
360
|
+
if ((decoded === null || decoded === void 0 ? void 0 : decoded.payload.firebase.tenant) && targetTenantId) {
|
|
361
|
+
errors_2.assert((decoded === null || decoded === void 0 ? void 0 : decoded.payload.firebase.tenant) === targetTenantId, "TENANT_ID_MISMATCH");
|
|
362
|
+
}
|
|
363
|
+
targetTenantId = targetTenantId || (decoded === null || decoded === void 0 ? void 0 : decoded.payload.firebase.tenant);
|
|
343
364
|
}
|
|
344
|
-
return operation(getProjectStateById(targetProjectId), ctx.requestBody, ctx);
|
|
365
|
+
return operation(getProjectStateById(targetProjectId, targetTenantId), ctx.requestBody, ctx);
|
|
345
366
|
};
|
|
346
367
|
}
|
|
347
368
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProjectState = exports.SIGNIN_METHOD_EMAIL_LINK = exports.PROVIDER_CUSTOM = exports.PROVIDER_ANONYMOUS = exports.PROVIDER_PHONE = exports.PROVIDER_PASSWORD = void 0;
|
|
3
|
+
exports.UsageMode = exports.TenantProjectState = exports.AgentProjectState = exports.ProjectState = exports.SIGNIN_METHOD_EMAIL_LINK = exports.PROVIDER_GAME_CENTER = exports.PROVIDER_CUSTOM = exports.PROVIDER_ANONYMOUS = exports.PROVIDER_PHONE = exports.PROVIDER_PASSWORD = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const cloudFunctions_1 = require("./cloudFunctions");
|
|
6
6
|
const errors_1 = require("./errors");
|
|
@@ -8,6 +8,7 @@ exports.PROVIDER_PASSWORD = "password";
|
|
|
8
8
|
exports.PROVIDER_PHONE = "phone";
|
|
9
9
|
exports.PROVIDER_ANONYMOUS = "anonymous";
|
|
10
10
|
exports.PROVIDER_CUSTOM = "custom";
|
|
11
|
+
exports.PROVIDER_GAME_CENTER = "gc.apple.com";
|
|
11
12
|
exports.SIGNIN_METHOD_EMAIL_LINK = "emailLink";
|
|
12
13
|
class ProjectState {
|
|
13
14
|
constructor(projectId) {
|
|
@@ -23,8 +24,6 @@ class ProjectState {
|
|
|
23
24
|
this.oobs = new Map();
|
|
24
25
|
this.verificationCodes = new Map();
|
|
25
26
|
this.temporaryProofs = new Map();
|
|
26
|
-
this.oneAccountPerEmail = true;
|
|
27
|
-
this.authCloudFunction = new cloudFunctions_1.AuthCloudFunction(projectId);
|
|
28
27
|
}
|
|
29
28
|
get projectNumber() {
|
|
30
29
|
return "12345";
|
|
@@ -281,10 +280,16 @@ class ProjectState {
|
|
|
281
280
|
getUserByLocalId(localId) {
|
|
282
281
|
return this.users.get(localId);
|
|
283
282
|
}
|
|
284
|
-
createRefreshTokenFor(userInfo, provider, extraClaims = {}) {
|
|
283
|
+
createRefreshTokenFor(userInfo, provider, { extraClaims = {}, secondFactor, } = {}) {
|
|
285
284
|
const localId = userInfo.localId;
|
|
286
285
|
const refreshToken = utils_1.randomBase64UrlStr(204);
|
|
287
|
-
this.refreshTokens.set(refreshToken, {
|
|
286
|
+
this.refreshTokens.set(refreshToken, {
|
|
287
|
+
localId,
|
|
288
|
+
provider,
|
|
289
|
+
extraClaims,
|
|
290
|
+
secondFactor,
|
|
291
|
+
tenantId: userInfo.tenantId,
|
|
292
|
+
});
|
|
288
293
|
let refreshTokens = this.refreshTokensForLocalId.get(localId);
|
|
289
294
|
if (!refreshTokens) {
|
|
290
295
|
refreshTokens = new Set();
|
|
@@ -302,6 +307,7 @@ class ProjectState {
|
|
|
302
307
|
user: this.getUserByLocalIdAssertingExists(record.localId),
|
|
303
308
|
provider: record.provider,
|
|
304
309
|
extraClaims: record.extraClaims,
|
|
310
|
+
secondFactor: record.secondFactor,
|
|
305
311
|
};
|
|
306
312
|
}
|
|
307
313
|
createOob(email, requestType, generateLink) {
|
|
@@ -413,6 +419,195 @@ class ProjectState {
|
|
|
413
419
|
}
|
|
414
420
|
}
|
|
415
421
|
exports.ProjectState = ProjectState;
|
|
422
|
+
class AgentProjectState extends ProjectState {
|
|
423
|
+
constructor(projectId) {
|
|
424
|
+
super(projectId);
|
|
425
|
+
this._oneAccountPerEmail = true;
|
|
426
|
+
this._usageMode = UsageMode.DEFAULT;
|
|
427
|
+
this.tenantProjectForTenantId = new Map();
|
|
428
|
+
this._authCloudFunction = new cloudFunctions_1.AuthCloudFunction(this.projectId);
|
|
429
|
+
}
|
|
430
|
+
get authCloudFunction() {
|
|
431
|
+
return this._authCloudFunction;
|
|
432
|
+
}
|
|
433
|
+
get oneAccountPerEmail() {
|
|
434
|
+
return this._oneAccountPerEmail;
|
|
435
|
+
}
|
|
436
|
+
set oneAccountPerEmail(oneAccountPerEmail) {
|
|
437
|
+
this._oneAccountPerEmail = oneAccountPerEmail;
|
|
438
|
+
}
|
|
439
|
+
get usageMode() {
|
|
440
|
+
return this._usageMode;
|
|
441
|
+
}
|
|
442
|
+
set usageMode(usageMode) {
|
|
443
|
+
this._usageMode = usageMode;
|
|
444
|
+
}
|
|
445
|
+
get allowPasswordSignup() {
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
get disableAuth() {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
get mfaConfig() {
|
|
452
|
+
return { state: "ENABLED", enabledProviders: ["PHONE_SMS"] };
|
|
453
|
+
}
|
|
454
|
+
get enableAnonymousUser() {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
get enableEmailLinkSignin() {
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
getTenantProject(tenantId) {
|
|
461
|
+
if (!this.tenantProjectForTenantId.has(tenantId)) {
|
|
462
|
+
this.createTenantWithTenantId(tenantId, {
|
|
463
|
+
tenantId,
|
|
464
|
+
allowPasswordSignup: true,
|
|
465
|
+
disableAuth: false,
|
|
466
|
+
mfaConfig: {
|
|
467
|
+
state: "ENABLED",
|
|
468
|
+
enabledProviders: ["PHONE_SMS"],
|
|
469
|
+
},
|
|
470
|
+
enableAnonymousUser: true,
|
|
471
|
+
enableEmailLinkSignin: true,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return this.tenantProjectForTenantId.get(tenantId);
|
|
475
|
+
}
|
|
476
|
+
listTenants(startToken) {
|
|
477
|
+
const tenantProjects = [];
|
|
478
|
+
for (const tenantProject of this.tenantProjectForTenantId.values()) {
|
|
479
|
+
if (!startToken || tenantProject.tenantId > startToken) {
|
|
480
|
+
tenantProjects.push(tenantProject);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
tenantProjects.sort((a, b) => {
|
|
484
|
+
if (a.tenantId < b.tenantId) {
|
|
485
|
+
return -1;
|
|
486
|
+
}
|
|
487
|
+
else if (a.tenantId > b.tenantId) {
|
|
488
|
+
return 1;
|
|
489
|
+
}
|
|
490
|
+
return 0;
|
|
491
|
+
});
|
|
492
|
+
return tenantProjects.map((tenantProject) => tenantProject.tenantConfig);
|
|
493
|
+
}
|
|
494
|
+
createTenant(tenant) {
|
|
495
|
+
for (let i = 0; i < 10; i++) {
|
|
496
|
+
const tenantId = utils_1.randomId(28);
|
|
497
|
+
const createdTenant = this.createTenantWithTenantId(tenantId, tenant);
|
|
498
|
+
if (createdTenant) {
|
|
499
|
+
return createdTenant;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
throw new Error("Could not generate a random unique tenantId after 10 tries");
|
|
503
|
+
}
|
|
504
|
+
createTenantWithTenantId(tenantId, tenant) {
|
|
505
|
+
if (this.tenantProjectForTenantId.has(tenantId)) {
|
|
506
|
+
return undefined;
|
|
507
|
+
}
|
|
508
|
+
tenant.name = `projects/${this.projectId}/tenants/${tenantId}`;
|
|
509
|
+
tenant.tenantId = tenantId;
|
|
510
|
+
this.tenantProjectForTenantId.set(tenantId, new TenantProjectState(this.projectId, tenantId, tenant, this));
|
|
511
|
+
return tenant;
|
|
512
|
+
}
|
|
513
|
+
deleteTenant(tenantId) {
|
|
514
|
+
this.tenantProjectForTenantId.delete(tenantId);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
exports.AgentProjectState = AgentProjectState;
|
|
518
|
+
class TenantProjectState extends ProjectState {
|
|
519
|
+
constructor(projectId, tenantId, _tenantConfig, parentProject) {
|
|
520
|
+
super(projectId);
|
|
521
|
+
this.tenantId = tenantId;
|
|
522
|
+
this._tenantConfig = _tenantConfig;
|
|
523
|
+
this.parentProject = parentProject;
|
|
524
|
+
}
|
|
525
|
+
get oneAccountPerEmail() {
|
|
526
|
+
return this.parentProject.oneAccountPerEmail;
|
|
527
|
+
}
|
|
528
|
+
get authCloudFunction() {
|
|
529
|
+
return this.parentProject.authCloudFunction;
|
|
530
|
+
}
|
|
531
|
+
get usageMode() {
|
|
532
|
+
return this.parentProject.usageMode;
|
|
533
|
+
}
|
|
534
|
+
get tenantConfig() {
|
|
535
|
+
return this._tenantConfig;
|
|
536
|
+
}
|
|
537
|
+
get allowPasswordSignup() {
|
|
538
|
+
return this._tenantConfig.allowPasswordSignup;
|
|
539
|
+
}
|
|
540
|
+
get disableAuth() {
|
|
541
|
+
return this._tenantConfig.disableAuth;
|
|
542
|
+
}
|
|
543
|
+
get mfaConfig() {
|
|
544
|
+
return this._tenantConfig.mfaConfig;
|
|
545
|
+
}
|
|
546
|
+
get enableAnonymousUser() {
|
|
547
|
+
return this._tenantConfig.enableAnonymousUser;
|
|
548
|
+
}
|
|
549
|
+
get enableEmailLinkSignin() {
|
|
550
|
+
return this._tenantConfig.enableEmailLinkSignin;
|
|
551
|
+
}
|
|
552
|
+
delete() {
|
|
553
|
+
this.parentProject.deleteTenant(this.tenantId);
|
|
554
|
+
}
|
|
555
|
+
updateTenant(update, updateMask) {
|
|
556
|
+
var _a, _b, _c, _d, _e;
|
|
557
|
+
if (!updateMask) {
|
|
558
|
+
const mfaConfig = (_a = update.mfaConfig) !== null && _a !== void 0 ? _a : {};
|
|
559
|
+
if (!("state" in mfaConfig)) {
|
|
560
|
+
mfaConfig.state = "DISABLED";
|
|
561
|
+
}
|
|
562
|
+
if (!("enabledProviders" in mfaConfig)) {
|
|
563
|
+
mfaConfig.enabledProviders = [];
|
|
564
|
+
}
|
|
565
|
+
this._tenantConfig = {
|
|
566
|
+
tenantId: this.tenantId,
|
|
567
|
+
name: this.tenantConfig.name,
|
|
568
|
+
allowPasswordSignup: (_b = update.allowPasswordSignup) !== null && _b !== void 0 ? _b : false,
|
|
569
|
+
disableAuth: (_c = update.disableAuth) !== null && _c !== void 0 ? _c : false,
|
|
570
|
+
mfaConfig: mfaConfig,
|
|
571
|
+
enableAnonymousUser: (_d = update.enableAnonymousUser) !== null && _d !== void 0 ? _d : false,
|
|
572
|
+
enableEmailLinkSignin: (_e = update.enableEmailLinkSignin) !== null && _e !== void 0 ? _e : false,
|
|
573
|
+
displayName: update.displayName,
|
|
574
|
+
};
|
|
575
|
+
return this.tenantConfig;
|
|
576
|
+
}
|
|
577
|
+
const paths = updateMask.split(",");
|
|
578
|
+
for (const path of paths) {
|
|
579
|
+
const fields = path.split(".");
|
|
580
|
+
let updateField = update;
|
|
581
|
+
let existingField = this._tenantConfig;
|
|
582
|
+
let field;
|
|
583
|
+
for (let i = 0; i < fields.length - 1; i++) {
|
|
584
|
+
field = fields[i];
|
|
585
|
+
if (updateField[field] == null) {
|
|
586
|
+
console.warn(`Unable to find field '${field}' in update '${updateField}`);
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
if (Array.isArray(updateField[field]) ||
|
|
590
|
+
Object(updateField[field]) !== updateField[field]) {
|
|
591
|
+
console.warn(`Field '${field}' is singular and cannot have sub-fields`);
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
if (!existingField[field]) {
|
|
595
|
+
existingField[field] = {};
|
|
596
|
+
}
|
|
597
|
+
updateField = updateField[field];
|
|
598
|
+
existingField = existingField[field];
|
|
599
|
+
}
|
|
600
|
+
field = fields[fields.length - 1];
|
|
601
|
+
if (updateField[field] == null) {
|
|
602
|
+
console.warn(`Unable to find field '${field}' in update '${JSON.stringify(updateField)}`);
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
existingField[field] = updateField[field];
|
|
606
|
+
}
|
|
607
|
+
return this.tenantConfig;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
exports.TenantProjectState = TenantProjectState;
|
|
416
611
|
function getProviderEmailsForUser(user) {
|
|
417
612
|
var _a;
|
|
418
613
|
const emails = new Set();
|
|
@@ -423,3 +618,8 @@ function getProviderEmailsForUser(user) {
|
|
|
423
618
|
});
|
|
424
619
|
return emails;
|
|
425
620
|
}
|
|
621
|
+
var UsageMode;
|
|
622
|
+
(function (UsageMode) {
|
|
623
|
+
UsageMode["DEFAULT"] = "DEFAULT";
|
|
624
|
+
UsageMode["PASSTHROUGH"] = "PASSTHROUGH";
|
|
625
|
+
})(UsageMode = exports.UsageMode || (exports.UsageMode = {}));
|
|
@@ -488,7 +488,7 @@ exports.WIDGET_UI = `
|
|
|
488
488
|
<meta charset="utf-8">
|
|
489
489
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
490
490
|
<title>Auth Emulator IDP Login Widget</title>
|
|
491
|
-
<link href="https://unpkg.com/material-components-web@
|
|
491
|
+
<link href="https://unpkg.com/material-components-web@10/dist/material-components-web.min.css" rel="stylesheet">
|
|
492
492
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
493
493
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
|
|
494
494
|
<style>${STYLE}</style>
|
|
@@ -601,6 +601,6 @@ exports.WIDGET_UI = `
|
|
|
601
601
|
</div>
|
|
602
602
|
</div>
|
|
603
603
|
</div>
|
|
604
|
-
<script src="https://unpkg.com/material-components-web@
|
|
604
|
+
<script src="https://unpkg.com/material-components-web@10/dist/material-components-web.min.js"></script>
|
|
605
605
|
<script>${SCRIPT}</script>
|
|
606
606
|
`;
|
package/lib/emulator/download.js
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.downloadEmulator = void 0;
|
|
4
|
-
const url_1 = require("url");
|
|
5
4
|
const crypto = require("crypto");
|
|
6
5
|
const fs = require("fs-extra");
|
|
7
6
|
const path = require("path");
|
|
8
|
-
const ProgressBar = require("progress");
|
|
9
7
|
const tmp = require("tmp");
|
|
10
8
|
const unzipper = require("unzipper");
|
|
11
|
-
const apiv2_1 = require("../apiv2");
|
|
12
9
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
13
10
|
const error_1 = require("../error");
|
|
14
11
|
const downloadableEmulators = require("./downloadableEmulators");
|
|
12
|
+
const downloadUtils = require("../downloadUtils");
|
|
15
13
|
tmp.setGracefulCleanup();
|
|
16
14
|
async function downloadEmulator(name) {
|
|
17
15
|
const emulator = downloadableEmulators.getDownloadDetails(name);
|
|
18
16
|
emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("BULLET", name, `downloading ${path.basename(emulator.downloadPath)}...`);
|
|
19
17
|
fs.ensureDirSync(emulator.opts.cacheDir);
|
|
20
|
-
const tmpfile = await downloadToTmp(emulator.opts.remoteUrl);
|
|
18
|
+
const tmpfile = await downloadUtils.downloadToTmp(emulator.opts.remoteUrl);
|
|
21
19
|
if (!emulator.opts.skipChecksumAndSize) {
|
|
22
20
|
await validateSize(tmpfile, emulator.opts.expectedSize);
|
|
23
21
|
await validateChecksum(tmpfile, emulator.opts.expectedChecksum);
|
|
@@ -58,33 +56,6 @@ function removeOldFiles(name, emulator, removeAllVersions = false) {
|
|
|
58
56
|
}
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
|
-
async function downloadToTmp(remoteUrl) {
|
|
62
|
-
const u = new url_1.URL(remoteUrl);
|
|
63
|
-
const c = new apiv2_1.Client({ urlPrefix: u.origin, auth: false });
|
|
64
|
-
const tmpfile = tmp.fileSync();
|
|
65
|
-
const writeStream = fs.createWriteStream(tmpfile.name);
|
|
66
|
-
const res = await c.request({
|
|
67
|
-
method: "GET",
|
|
68
|
-
path: u.pathname,
|
|
69
|
-
queryParams: u.searchParams,
|
|
70
|
-
responseType: "stream",
|
|
71
|
-
resolveOnHTTPError: true,
|
|
72
|
-
});
|
|
73
|
-
if (res.status !== 200) {
|
|
74
|
-
throw new error_1.FirebaseError(`download failed, status ${res.status}`, { exit: 1 });
|
|
75
|
-
}
|
|
76
|
-
const total = parseInt(res.response.headers.get("content-length") || "0", 10);
|
|
77
|
-
const totalMb = Math.ceil(total / 1000000);
|
|
78
|
-
const bar = new ProgressBar(`Progress: :bar (:percent of ${totalMb}MB)`, { total, head: ">" });
|
|
79
|
-
res.body.on("data", (chunk) => {
|
|
80
|
-
bar.tick(chunk.length);
|
|
81
|
-
});
|
|
82
|
-
await new Promise((resolve) => {
|
|
83
|
-
writeStream.on("finish", resolve);
|
|
84
|
-
res.body.pipe(writeStream);
|
|
85
|
-
});
|
|
86
|
-
return tmpfile.name;
|
|
87
|
-
}
|
|
88
59
|
function validateSize(filepath, expectedSize) {
|
|
89
60
|
return new Promise((resolve, reject) => {
|
|
90
61
|
const stat = fs.statSync(filepath);
|
|
@@ -50,15 +50,15 @@ exports.DownloadDetails = {
|
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
52
|
ui: {
|
|
53
|
-
version: "1.6.
|
|
54
|
-
downloadPath: path.join(CACHE_DIR, "ui-v1.6.
|
|
55
|
-
unzipDir: path.join(CACHE_DIR, "ui-v1.6.
|
|
56
|
-
binaryPath: path.join(CACHE_DIR, "ui-v1.6.
|
|
53
|
+
version: "1.6.4",
|
|
54
|
+
downloadPath: path.join(CACHE_DIR, "ui-v1.6.4.zip"),
|
|
55
|
+
unzipDir: path.join(CACHE_DIR, "ui-v1.6.4"),
|
|
56
|
+
binaryPath: path.join(CACHE_DIR, "ui-v1.6.4", "server.bundle.js"),
|
|
57
57
|
opts: {
|
|
58
58
|
cacheDir: CACHE_DIR,
|
|
59
|
-
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/ui-v1.6.
|
|
60
|
-
expectedSize:
|
|
61
|
-
expectedChecksum: "
|
|
59
|
+
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/ui-v1.6.4.zip",
|
|
60
|
+
expectedSize: 3757300,
|
|
61
|
+
expectedChecksum: "20d4ee71e4ff7527b1843b6a8636142e",
|
|
62
62
|
namePrefix: "ui",
|
|
63
63
|
},
|
|
64
64
|
},
|
|
@@ -168,9 +168,6 @@ You can probably fix this by running "npm install ${systemLog.data.name}@latest"
|
|
|
168
168
|
case "function-runtimeconfig-json-invalid":
|
|
169
169
|
this.log("WARN", "Found .runtimeconfig.json but the JSON format is invalid.");
|
|
170
170
|
break;
|
|
171
|
-
case "function-env-load-failed":
|
|
172
|
-
this.log("WARN", "Failed to load environment variables: " + systemLog.text);
|
|
173
|
-
break;
|
|
174
171
|
default:
|
|
175
172
|
}
|
|
176
173
|
}
|
|
@@ -9,5 +9,21 @@ class EventUtils {
|
|
|
9
9
|
static isLegacyEvent(proto) {
|
|
10
10
|
return _.has(proto, "data") && _.has(proto, "resource");
|
|
11
11
|
}
|
|
12
|
+
static isBinaryCloudEvent(req) {
|
|
13
|
+
return !!(req.header("ce-type") &&
|
|
14
|
+
req.header("ce-specversion") &&
|
|
15
|
+
req.header("ce-source") &&
|
|
16
|
+
req.header("ce-id"));
|
|
17
|
+
}
|
|
18
|
+
static extractBinaryCloudEventContext(req) {
|
|
19
|
+
const context = {};
|
|
20
|
+
for (const name of Object.keys(req.headers)) {
|
|
21
|
+
if (name.startsWith("ce-")) {
|
|
22
|
+
const attributeName = name.substr("ce-".length);
|
|
23
|
+
context[attributeName] = req.header(name);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
12
28
|
}
|
|
13
29
|
exports.EventUtils = EventUtils;
|