Açıklama Yok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

provisioningHelper.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.getUsedProducts = exports.bulkCheckProductsProvisioned = exports.checkProductsProvisioned = exports.DeferredProduct = void 0;
  4. const { marked } = require("marked");
  5. const api_1 = require("../api");
  6. const apiv2_1 = require("../apiv2");
  7. const functional_1 = require("../functional");
  8. const error_1 = require("../error");
  9. const planner_1 = require("../deploy/extensions/planner");
  10. const logger_1 = require("../logger");
  11. var DeferredProduct;
  12. (function (DeferredProduct) {
  13. DeferredProduct[DeferredProduct["STORAGE"] = 0] = "STORAGE";
  14. DeferredProduct[DeferredProduct["AUTH"] = 1] = "AUTH";
  15. })(DeferredProduct = exports.DeferredProduct || (exports.DeferredProduct = {}));
  16. async function checkProductsProvisioned(projectId, spec) {
  17. const usedProducts = getUsedProducts(spec);
  18. await checkProducts(projectId, usedProducts);
  19. }
  20. exports.checkProductsProvisioned = checkProductsProvisioned;
  21. async function bulkCheckProductsProvisioned(projectId, instanceSpecs) {
  22. const usedProducts = await Promise.all(instanceSpecs.map(async (i) => {
  23. const extensionSpec = await (0, planner_1.getExtensionSpec)(i);
  24. return getUsedProducts(extensionSpec);
  25. }));
  26. await checkProducts(projectId, [...(0, functional_1.flattenArray)(usedProducts)]);
  27. }
  28. exports.bulkCheckProductsProvisioned = bulkCheckProductsProvisioned;
  29. async function checkProducts(projectId, usedProducts) {
  30. const needProvisioning = [];
  31. let isStorageProvisionedPromise;
  32. let isAuthProvisionedPromise;
  33. if (usedProducts.includes(DeferredProduct.STORAGE)) {
  34. isStorageProvisionedPromise = isStorageProvisioned(projectId);
  35. }
  36. if (usedProducts.includes(DeferredProduct.AUTH)) {
  37. isAuthProvisionedPromise = isAuthProvisioned(projectId);
  38. }
  39. try {
  40. if (isStorageProvisionedPromise && !(await isStorageProvisionedPromise)) {
  41. needProvisioning.push(DeferredProduct.STORAGE);
  42. }
  43. if (isAuthProvisionedPromise && !(await isAuthProvisionedPromise)) {
  44. needProvisioning.push(DeferredProduct.AUTH);
  45. }
  46. }
  47. catch (err) {
  48. logger_1.logger.debug(`Error while checking product provisioning, failing open: ${err}`);
  49. }
  50. if (needProvisioning.length > 0) {
  51. let errorMessage = "Some services used by this extension have not been set up on your " +
  52. "Firebase project. To ensure this extension works as intended, you must enable these " +
  53. "services by following the provided links, then retry this command\n\n";
  54. if (needProvisioning.includes(DeferredProduct.STORAGE)) {
  55. errorMessage +=
  56. " - Firebase Storage: store and retrieve user-generated files like images, audio, and " +
  57. "video without server-side code.\n";
  58. errorMessage += ` https://console.firebase.google.com/project/${projectId}/storage`;
  59. errorMessage += "\n";
  60. }
  61. if (needProvisioning.includes(DeferredProduct.AUTH)) {
  62. errorMessage +=
  63. " - Firebase Authentication: authenticate and manage users from a variety of providers " +
  64. "without server-side code.\n";
  65. errorMessage += ` https://console.firebase.google.com/project/${projectId}/authentication/users`;
  66. }
  67. throw new error_1.FirebaseError(marked(errorMessage), { exit: 2 });
  68. }
  69. }
  70. function getUsedProducts(spec) {
  71. var _a, _b;
  72. const usedProducts = [];
  73. const usedApis = (_a = spec.apis) === null || _a === void 0 ? void 0 : _a.map((api) => api.apiName);
  74. const usedRoles = (_b = spec.roles) === null || _b === void 0 ? void 0 : _b.map((r) => r.role.split(".")[0]);
  75. const usedTriggers = spec.resources.map((r) => getTriggerType(r.propertiesYaml));
  76. if ((usedApis === null || usedApis === void 0 ? void 0 : usedApis.includes("storage-component.googleapis.com")) ||
  77. (usedRoles === null || usedRoles === void 0 ? void 0 : usedRoles.includes("storage")) ||
  78. usedTriggers.find((t) => t === null || t === void 0 ? void 0 : t.startsWith("google.storage."))) {
  79. usedProducts.push(DeferredProduct.STORAGE);
  80. }
  81. if ((usedApis === null || usedApis === void 0 ? void 0 : usedApis.includes("identitytoolkit.googleapis.com")) ||
  82. (usedRoles === null || usedRoles === void 0 ? void 0 : usedRoles.includes("firebaseauth")) ||
  83. usedTriggers.find((t) => t === null || t === void 0 ? void 0 : t.startsWith("providers/firebase.auth/"))) {
  84. usedProducts.push(DeferredProduct.AUTH);
  85. }
  86. return usedProducts;
  87. }
  88. exports.getUsedProducts = getUsedProducts;
  89. function getTriggerType(propertiesYaml) {
  90. var _a;
  91. return (_a = propertiesYaml === null || propertiesYaml === void 0 ? void 0 : propertiesYaml.match(/eventType:\ ([\S]+)/)) === null || _a === void 0 ? void 0 : _a[1];
  92. }
  93. async function isStorageProvisioned(projectId) {
  94. var _a, _b;
  95. const client = new apiv2_1.Client({ urlPrefix: api_1.firebaseStorageOrigin, apiVersion: "v1beta" });
  96. const resp = await client.get(`/projects/${projectId}/buckets`);
  97. return !!((_b = (_a = resp.body) === null || _a === void 0 ? void 0 : _a.buckets) === null || _b === void 0 ? void 0 : _b.find((bucket) => {
  98. const bucketResourceName = bucket.name;
  99. const bucketResourceNameTokens = bucketResourceName.split("/");
  100. const pattern = "^" + projectId + "(.[[a-z0-9]+)*.appspot.com$";
  101. return new RegExp(pattern).test(bucketResourceNameTokens[bucketResourceNameTokens.length - 1]);
  102. }));
  103. }
  104. async function isAuthProvisioned(projectId) {
  105. var _a, _b;
  106. const client = new apiv2_1.Client({ urlPrefix: api_1.firedataOrigin, apiVersion: "v1" });
  107. const resp = await client.get(`/projects/${projectId}/products`);
  108. return !!((_b = (_a = resp.body) === null || _a === void 0 ? void 0 : _a.activation) === null || _b === void 0 ? void 0 : _b.map((a) => a.service).includes("FIREBASE_AUTH"));
  109. }