firebase-tools 13.33.0 → 13.35.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 (38) hide show
  1. package/lib/apphosting/config.js +8 -6
  2. package/lib/apphosting/yaml.js +21 -48
  3. package/lib/commands/dataconnect-sdk-generate.js +4 -1
  4. package/lib/commands/dataconnect-sql-diff.js +1 -1
  5. package/lib/commands/dataconnect-sql-grant.js +2 -2
  6. package/lib/commands/dataconnect-sql-setup.js +40 -0
  7. package/lib/commands/functions-artifacts-setpolicy.js +125 -0
  8. package/lib/commands/index.js +3 -0
  9. package/lib/commands/open.js +3 -0
  10. package/lib/dataconnect/build.js +3 -1
  11. package/lib/dataconnect/fileUtils.js +8 -4
  12. package/lib/dataconnect/schemaMigration.js +38 -12
  13. package/lib/defaultCredentials.js +12 -1
  14. package/lib/deploy/dataconnect/prepare.js +1 -1
  15. package/lib/deploy/functions/containerCleaner.js +17 -2
  16. package/lib/deploy/functions/runtimes/discovery/index.js +3 -1
  17. package/lib/deploy/index.js +22 -20
  18. package/lib/emulator/ExpressBasedEmulator.js +1 -1
  19. package/lib/emulator/apphosting/index.js +1 -0
  20. package/lib/emulator/apphosting/serve.js +48 -7
  21. package/lib/emulator/controller.js +1 -0
  22. package/lib/emulator/dataconnect/pgliteServer.js +7 -2
  23. package/lib/emulator/dataconnectEmulator.js +15 -4
  24. package/lib/emulator/downloadableEmulators.js +9 -9
  25. package/lib/emulator/env.js +17 -1
  26. package/lib/emulator/functionsEmulator.js +2 -20
  27. package/lib/extensions/extensionsHelper.js +8 -4
  28. package/lib/frameworks/angular/utils.js +60 -42
  29. package/lib/functions/artifacts.js +104 -0
  30. package/lib/gcp/artifactregistry.js +27 -2
  31. package/lib/gcp/cloudsql/cloudsqladmin.js +22 -1
  32. package/lib/gcp/cloudsql/connect.js +21 -14
  33. package/lib/gcp/cloudsql/permissions.js +45 -99
  34. package/lib/gcp/cloudsql/permissions_setup.js +215 -0
  35. package/lib/init/features/dataconnect/index.js +1 -1
  36. package/lib/init/features/dataconnect/sdk.js +23 -3
  37. package/package.json +1 -1
  38. package/templates/init/dataconnect/connector.yaml +1 -1
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasCleanupOptOut = exports.hasSameCleanupPolicy = exports.setCleanupPolicy = exports.optOutRepository = exports.updateRepository = exports.generateCleanupPolicy = exports.parseDaysFromPolicy = exports.daysToSeconds = exports.findExistingPolicy = exports.makeRepoPath = exports.OPT_OUT_LABEL_KEY = exports.CLEANUP_POLICY_ID = exports.GCF_REPO_ID = void 0;
4
+ const artifactregistry = require("../gcp/artifactregistry");
5
+ const error_1 = require("../error");
6
+ exports.GCF_REPO_ID = "gcf-artifacts";
7
+ exports.CLEANUP_POLICY_ID = "firebase-functions-cleanup";
8
+ exports.OPT_OUT_LABEL_KEY = "firebase-functions-cleanup-opted-out";
9
+ const SECONDS_IN_DAY = 24 * 60 * 60;
10
+ function makeRepoPath(projectId, location, repoName = exports.GCF_REPO_ID) {
11
+ return `projects/${projectId}/locations/${location}/repositories/${repoName}`;
12
+ }
13
+ exports.makeRepoPath = makeRepoPath;
14
+ function findExistingPolicy(repository) {
15
+ var _a;
16
+ return (_a = repository === null || repository === void 0 ? void 0 : repository.cleanupPolicies) === null || _a === void 0 ? void 0 : _a[exports.CLEANUP_POLICY_ID];
17
+ }
18
+ exports.findExistingPolicy = findExistingPolicy;
19
+ function daysToSeconds(days) {
20
+ const seconds = days * SECONDS_IN_DAY;
21
+ return `${seconds}s`;
22
+ }
23
+ exports.daysToSeconds = daysToSeconds;
24
+ function parseDaysFromPolicy(olderThan) {
25
+ const match = olderThan.match(/^(\d+)s$/);
26
+ if (match && match[1]) {
27
+ const seconds = parseInt(match[1], 10);
28
+ return Math.floor(seconds / SECONDS_IN_DAY);
29
+ }
30
+ return;
31
+ }
32
+ exports.parseDaysFromPolicy = parseDaysFromPolicy;
33
+ function generateCleanupPolicy(daysToKeep) {
34
+ return {
35
+ [exports.CLEANUP_POLICY_ID]: {
36
+ id: exports.CLEANUP_POLICY_ID,
37
+ condition: {
38
+ tagState: "ANY",
39
+ olderThan: daysToSeconds(daysToKeep),
40
+ },
41
+ action: "DELETE",
42
+ },
43
+ };
44
+ }
45
+ exports.generateCleanupPolicy = generateCleanupPolicy;
46
+ async function updateRepository(repo) {
47
+ try {
48
+ await artifactregistry.updateRepository(repo);
49
+ }
50
+ catch (err) {
51
+ if (err.status === 403) {
52
+ throw new error_1.FirebaseError(`You don't have permission to update this repository.\n` +
53
+ `To update repository settings, ask your administrator to grant you the ` +
54
+ `Artifact Registry Administrator (roles/artifactregistry.admin) IAM role on the repository project.`, { original: err, exit: 1 });
55
+ }
56
+ else {
57
+ throw new error_1.FirebaseError("Failed to update artifact registry repository", {
58
+ original: err,
59
+ });
60
+ }
61
+ }
62
+ }
63
+ exports.updateRepository = updateRepository;
64
+ async function optOutRepository(repository) {
65
+ const policies = Object.assign({}, repository.cleanupPolicies);
66
+ if (exports.CLEANUP_POLICY_ID in policies) {
67
+ delete policies[exports.CLEANUP_POLICY_ID];
68
+ }
69
+ const update = {
70
+ name: repository.name,
71
+ labels: Object.assign(Object.assign({}, repository.labels), { [exports.OPT_OUT_LABEL_KEY]: "true" }),
72
+ cleanupPolicies: policies,
73
+ };
74
+ await exports.updateRepository(update);
75
+ }
76
+ exports.optOutRepository = optOutRepository;
77
+ async function setCleanupPolicy(repository, daysToKeep) {
78
+ const labels = Object.assign({}, repository.labels);
79
+ delete labels[exports.OPT_OUT_LABEL_KEY];
80
+ const update = {
81
+ name: repository.name,
82
+ cleanupPolicies: Object.assign(Object.assign({}, repository.cleanupPolicies), generateCleanupPolicy(daysToKeep)),
83
+ labels,
84
+ };
85
+ await exports.updateRepository(update);
86
+ }
87
+ exports.setCleanupPolicy = setCleanupPolicy;
88
+ function hasSameCleanupPolicy(repository, daysToKeep) {
89
+ var _a, _b;
90
+ const existingPolicy = findExistingPolicy(repository);
91
+ if (!existingPolicy) {
92
+ return false;
93
+ }
94
+ if (((_a = existingPolicy.condition) === null || _a === void 0 ? void 0 : _a.tagState) !== "ANY" || !((_b = existingPolicy.condition) === null || _b === void 0 ? void 0 : _b.olderThan)) {
95
+ return false;
96
+ }
97
+ const existingSeconds = parseDaysFromPolicy(existingPolicy.condition.olderThan);
98
+ return existingSeconds === daysToKeep;
99
+ }
100
+ exports.hasSameCleanupPolicy = hasSameCleanupPolicy;
101
+ function hasCleanupOptOut(repo) {
102
+ return !!(repo.labels && repo.labels[exports.OPT_OUT_LABEL_KEY] === "true");
103
+ }
104
+ exports.hasCleanupOptOut = hasCleanupOptOut;
@@ -1,16 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deletePackage = exports.API_VERSION = void 0;
3
+ exports.updateRepository = exports.getRepository = exports.deletePackage = exports.ensureApiEnabled = exports.API_VERSION = void 0;
4
4
  const apiv2_1 = require("../apiv2");
5
5
  const api_1 = require("../api");
6
- exports.API_VERSION = "v1beta2";
6
+ const metaprogramming_1 = require("../metaprogramming");
7
+ const api = require("../ensureApiEnabled");
8
+ const proto = require("./proto");
9
+ exports.API_VERSION = "v1";
7
10
  const client = new apiv2_1.Client({
8
11
  urlPrefix: (0, api_1.artifactRegistryDomain)(),
9
12
  auth: true,
10
13
  apiVersion: exports.API_VERSION,
11
14
  });
15
+ function ensureApiEnabled(projectId) {
16
+ return api.ensure(projectId, (0, api_1.artifactRegistryDomain)(), "artifactregistry", true);
17
+ }
18
+ exports.ensureApiEnabled = ensureApiEnabled;
19
+ (0, metaprogramming_1.assertImplements)();
12
20
  async function deletePackage(name) {
13
21
  const res = await client.delete(name);
14
22
  return res.body;
15
23
  }
16
24
  exports.deletePackage = deletePackage;
25
+ async function getRepository(repoPath) {
26
+ const res = await client.get(repoPath);
27
+ return res.body;
28
+ }
29
+ exports.getRepository = getRepository;
30
+ async function updateRepository(repo) {
31
+ const updateMask = proto.fieldMasks(repo, "cleanupPolicies", "labels");
32
+ if (updateMask.length === 0) {
33
+ const res = await client.get(repo.name);
34
+ return res.body;
35
+ }
36
+ const res = await client.patch(`/${repo.name}`, repo, {
37
+ queryParams: { updateMask: updateMask.join(",") },
38
+ });
39
+ return res.body;
40
+ }
41
+ exports.updateRepository = updateRepository;
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.listUsers = exports.deleteUser = exports.getUser = exports.createUser = exports.deleteDatabase = exports.createDatabase = exports.getDatabase = exports.listDatabases = exports.updateInstanceForDataConnect = exports.createInstance = exports.instanceConsoleLink = exports.getInstance = exports.listInstances = void 0;
3
+ exports.listUsers = exports.deleteUser = exports.getUser = exports.createUser = exports.deleteDatabase = exports.createDatabase = exports.getDatabase = exports.listDatabases = exports.updateInstanceForDataConnect = exports.createInstance = exports.instanceConsoleLink = exports.getInstance = exports.listInstances = exports.iamUserIsCSQLAdmin = void 0;
4
4
  const apiv2_1 = require("../../apiv2");
5
5
  const api_1 = require("../../api");
6
6
  const operationPoller = require("../../operation-poller");
7
+ const projectUtils_1 = require("../../projectUtils");
8
+ const logger_1 = require("../../logger");
9
+ const iam_1 = require("../iam");
7
10
  const error_1 = require("../../error");
8
11
  const API_VERSION = "v1";
9
12
  const client = new apiv2_1.Client({
@@ -11,6 +14,24 @@ const client = new apiv2_1.Client({
11
14
  auth: true,
12
15
  apiVersion: API_VERSION,
13
16
  });
17
+ async function iamUserIsCSQLAdmin(options) {
18
+ const projectId = (0, projectUtils_1.needProjectId)(options);
19
+ const requiredPermissions = [
20
+ "cloudsql.instances.connect",
21
+ "cloudsql.instances.get",
22
+ "cloudsql.users.create",
23
+ "cloudsql.users.update",
24
+ ];
25
+ try {
26
+ const iamResult = await (0, iam_1.testIamPermissions)(projectId, requiredPermissions);
27
+ return iamResult.passed;
28
+ }
29
+ catch (err) {
30
+ logger_1.logger.debug(`[iam] error while checking permissions, command may fail: ${err}`);
31
+ return false;
32
+ }
33
+ }
34
+ exports.iamUserIsCSQLAdmin = iamUserIsCSQLAdmin;
14
35
  async function listInstances(projectId) {
15
36
  var _a;
16
37
  const res = await client.get(`projects/${projectId}/instances`);
@@ -11,7 +11,6 @@ const utils = require("../../utils");
11
11
  const logger_1 = require("../../logger");
12
12
  const error_1 = require("../../error");
13
13
  const fbToolsAuthClient_1 = require("./fbToolsAuthClient");
14
- const permissions_1 = require("./permissions");
15
14
  async function execute(sqlStatements, opts) {
16
15
  const logFn = opts.silent ? logger_1.logger.debug : logger_1.logger.info;
17
16
  const instance = await cloudSqlAdminClient.getInstance(opts.projectId, opts.instanceId);
@@ -60,23 +59,35 @@ async function execute(sqlStatements, opts) {
60
59
  break;
61
60
  }
62
61
  }
62
+ const cleanUpFn = async () => {
63
+ conn.release();
64
+ await pool.end();
65
+ connector.close();
66
+ };
63
67
  const conn = await pool.connect();
68
+ const results = [];
64
69
  logFn(`Logged in as ${opts.username}`);
70
+ if (opts.transaction) {
71
+ sqlStatements.unshift("BEGIN;");
72
+ sqlStatements.push("COMMIT;");
73
+ }
65
74
  for (const s of sqlStatements) {
66
75
  logFn(`Executing: '${s}'`);
67
76
  try {
68
- await conn.query(s);
77
+ results.push(await conn.query(s));
69
78
  }
70
79
  catch (err) {
80
+ logFn(`Rolling back transaction due to error ${err}}`);
81
+ await conn.query("ROLLBACK;");
82
+ await cleanUpFn();
71
83
  throw new error_1.FirebaseError(`Error executing ${err}`);
72
84
  }
73
85
  }
74
- conn.release();
75
- await pool.end();
76
- connector.close();
86
+ await cleanUpFn();
87
+ return results;
77
88
  }
78
89
  exports.execute = execute;
79
- async function executeSqlCmdsAsIamUser(options, instanceId, databaseId, cmds, silent = false) {
90
+ async function executeSqlCmdsAsIamUser(options, instanceId, databaseId, cmds, silent = false, transaction = false) {
80
91
  const projectId = (0, projectUtils_1.needProjectId)(options);
81
92
  const { user: iamUser } = await getIAMUser(options);
82
93
  return await execute(cmds, {
@@ -85,21 +96,23 @@ async function executeSqlCmdsAsIamUser(options, instanceId, databaseId, cmds, si
85
96
  databaseId,
86
97
  username: iamUser,
87
98
  silent: silent,
99
+ transaction: transaction,
88
100
  });
89
101
  }
90
102
  exports.executeSqlCmdsAsIamUser = executeSqlCmdsAsIamUser;
91
- async function executeSqlCmdsAsSuperUser(options, instanceId, databaseId, cmds, silent = false) {
103
+ async function executeSqlCmdsAsSuperUser(options, instanceId, databaseId, cmds, silent = false, transaction = false) {
92
104
  const projectId = (0, projectUtils_1.needProjectId)(options);
93
105
  const superuser = "firebasesuperuser";
94
106
  const temporaryPassword = utils.generateId(20);
95
107
  await cloudSqlAdminClient.createUser(projectId, instanceId, "BUILT_IN", superuser, temporaryPassword);
96
- return await execute([`SET ROLE = cloudsqlsuperuser`, ...cmds], {
108
+ return await execute([`SET ROLE = '${superuser}'`, ...cmds], {
97
109
  projectId,
98
110
  instanceId,
99
111
  databaseId,
100
112
  username: superuser,
101
113
  password: temporaryPassword,
102
114
  silent: silent,
115
+ transaction: transaction,
103
116
  });
104
117
  }
105
118
  exports.executeSqlCmdsAsSuperUser = executeSqlCmdsAsSuperUser;
@@ -122,12 +135,6 @@ async function setupIAMUsers(instanceId, databaseId, options) {
122
135
  const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
123
136
  const { user: fdcP4SAUser, mode: fdcP4SAmode } = toDatabaseUser(getDataConnectP4SA(projectNumber));
124
137
  await cloudSqlAdminClient.createUser(projectId, instanceId, fdcP4SAmode, fdcP4SAUser);
125
- await (0, permissions_1.setupSQLPermissions)(instanceId, databaseId, options, true);
126
- const grants = [
127
- `GRANT "${(0, permissions_1.firebaseowner)(databaseId)}" TO "${user}"`,
128
- `GRANT "${(0, permissions_1.firebasewriter)(databaseId)}" TO "${fdcP4SAUser}"`,
129
- ];
130
- await executeSqlCmdsAsSuperUser(options, instanceId, databaseId, grants, true);
131
138
  return user;
132
139
  }
133
140
  exports.setupIAMUsers = setupIAMUsers;
@@ -1,89 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setupSQLPermissions = exports.iamUserIsCSQLAdmin = exports.checkSQLRoleIsGranted = exports.fdcSqlRoleMap = exports.firebasewriter = exports.firebasereader = exports.firebaseowner = void 0;
4
- const projectUtils_1 = require("../../projectUtils");
5
- const connect_1 = require("./connect");
6
- const iam_1 = require("../iam");
7
- const logger_1 = require("../../logger");
8
- const lodash_1 = require("lodash");
9
- const error_1 = require("../../error");
10
- function firebaseowner(databaseId) {
11
- return `firebaseowner_${databaseId}_public`;
3
+ exports.defaultPermissions = exports.readerRolePermissions = exports.writerRolePermissions = exports.ownerRolePermissions = exports.firebasewriter = exports.firebasereader = exports.firebaseowner = exports.FIREBASE_SUPER_USER = exports.DEFAULT_SCHEMA = void 0;
4
+ exports.DEFAULT_SCHEMA = "public";
5
+ exports.FIREBASE_SUPER_USER = "firebasesuperuser";
6
+ function firebaseowner(databaseId, schema = exports.DEFAULT_SCHEMA) {
7
+ return `firebaseowner_${databaseId}_${schema}`;
12
8
  }
13
9
  exports.firebaseowner = firebaseowner;
14
- function firebasereader(databaseId) {
15
- return `firebasereader_${databaseId}_public`;
10
+ function firebasereader(databaseId, schema = exports.DEFAULT_SCHEMA) {
11
+ return `firebasereader_${databaseId}_${schema}`;
16
12
  }
17
13
  exports.firebasereader = firebasereader;
18
- function firebasewriter(databaseId) {
19
- return `firebasewriter_${databaseId}_public`;
14
+ function firebasewriter(databaseId, schema = exports.DEFAULT_SCHEMA) {
15
+ return `firebasewriter_${databaseId}_${schema}`;
20
16
  }
21
17
  exports.firebasewriter = firebasewriter;
22
- exports.fdcSqlRoleMap = {
23
- owner: firebaseowner,
24
- writer: firebasewriter,
25
- reader: firebasereader,
26
- };
27
- async function checkSQLRoleIsGranted(options, instanceId, databaseId, grantedRole, granteeRole) {
28
- const checkCmd = `
29
- DO $$
30
- DECLARE
31
- role_count INTEGER;
32
- BEGIN
33
- -- Count the number of rows matching the criteria
34
- SELECT COUNT(*)
35
- INTO role_count
36
- FROM
37
- pg_auth_members m
38
- JOIN
39
- pg_roles grantee ON grantee.oid = m.member
40
- JOIN
41
- pg_roles granted ON granted.oid = m.roleid
42
- JOIN
43
- pg_roles grantor ON grantor.oid = m.grantor
44
- WHERE
45
- granted.rolname = '${grantedRole}'
46
- AND grantee.rolname = '${granteeRole}';
47
-
48
- -- If no rows were found, raise an exception
49
- IF role_count = 0 THEN
50
- RAISE EXCEPTION 'Role "%", is not granted to role "%".', '${grantedRole}', '${granteeRole}';
51
- END IF;
52
- END $$;
53
- `;
54
- try {
55
- await (0, connect_1.executeSqlCmdsAsIamUser)(options, instanceId, databaseId, [checkCmd], true);
56
- return true;
57
- }
58
- catch (e) {
59
- if (e instanceof error_1.FirebaseError && e.message.includes("not granted to role")) {
60
- return false;
61
- }
62
- logger_1.logger.error(`Role Check Failed: ${e}`);
63
- throw e;
64
- }
65
- }
66
- exports.checkSQLRoleIsGranted = checkSQLRoleIsGranted;
67
- async function iamUserIsCSQLAdmin(options) {
68
- const projectId = (0, projectUtils_1.needProjectId)(options);
69
- const requiredPermissions = [
70
- "cloudsql.instances.connect",
71
- "cloudsql.instances.get",
72
- "cloudsql.users.create",
73
- "cloudsql.users.update",
74
- ];
75
- try {
76
- const iamResult = await (0, iam_1.testIamPermissions)(projectId, requiredPermissions);
77
- return iamResult.passed;
78
- }
79
- catch (err) {
80
- logger_1.logger.debug(`[iam] error while checking permissions, command may fail: ${err}`);
81
- return false;
82
- }
83
- }
84
- exports.iamUserIsCSQLAdmin = iamUserIsCSQLAdmin;
85
18
  function ownerRolePermissions(databaseId, superuser, schema) {
86
- const firebaseOwnerRole = firebaseowner(databaseId);
19
+ const firebaseOwnerRole = firebaseowner(databaseId, schema);
87
20
  return [
88
21
  `do
89
22
  $$
@@ -102,8 +35,9 @@ function ownerRolePermissions(databaseId, superuser, schema) {
102
35
  `GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA "${schema}" TO "${firebaseOwnerRole}"`,
103
36
  ];
104
37
  }
38
+ exports.ownerRolePermissions = ownerRolePermissions;
105
39
  function writerRolePermissions(databaseId, superuser, schema) {
106
- const firebaseWriterRole = firebasewriter(databaseId);
40
+ const firebaseWriterRole = firebasewriter(databaseId, schema);
107
41
  return [
108
42
  `do
109
43
  $$
@@ -120,15 +54,11 @@ function writerRolePermissions(databaseId, superuser, schema) {
120
54
  `GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA "${schema}" TO "${firebaseWriterRole}"`,
121
55
  `GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA "${schema}" TO "${firebaseWriterRole}"`,
122
56
  `GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "${schema}" TO "${firebaseWriterRole}"`,
123
- `SET ROLE = '${firebaseowner(databaseId)}';`,
124
- `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO "${firebaseWriterRole}";`,
125
- `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT USAGE ON SEQUENCES TO "${firebaseWriterRole}";`,
126
- `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT EXECUTE ON FUNCTIONS TO "${firebaseWriterRole}"`,
127
- `SET ROLE = cloudsqlsuperuser`,
128
57
  ];
129
58
  }
59
+ exports.writerRolePermissions = writerRolePermissions;
130
60
  function readerRolePermissions(databaseId, superuser, schema) {
131
- const firebaseReaderRole = firebasereader(databaseId);
61
+ const firebaseReaderRole = firebasereader(databaseId, schema);
132
62
  return [
133
63
  `do
134
64
  $$
@@ -145,21 +75,37 @@ function readerRolePermissions(databaseId, superuser, schema) {
145
75
  `GRANT SELECT ON ALL TABLES IN SCHEMA "${schema}" TO "${firebaseReaderRole}"`,
146
76
  `GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA "${schema}" TO "${firebaseReaderRole}"`,
147
77
  `GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "${schema}" TO "${firebaseReaderRole}"`,
148
- `SET ROLE = '${firebaseowner(databaseId)}';`,
149
- `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT SELECT ON TABLES TO "${firebaseReaderRole}";`,
150
- `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT SELECT, USAGE ON SEQUENCES TO "${firebaseReaderRole}";`,
151
- `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT EXECUTE ON FUNCTIONS TO "${firebaseReaderRole}"`,
152
- `SET ROLE = cloudsqlsuperuser`,
153
78
  ];
154
79
  }
155
- async function setupSQLPermissions(instanceId, databaseId, options, silent = false) {
156
- const superuser = "firebasesuperuser";
157
- const revokes = [];
158
- if (await checkSQLRoleIsGranted(options, instanceId, databaseId, "cloudsqlsuperuser", firebaseowner(databaseId))) {
159
- logger_1.logger.warn("Detected cloudsqlsuperuser was previously given to firebase owner, revoking to improve database security.");
160
- revokes.push(`REVOKE "cloudsqlsuperuser" FROM "${firebaseowner(databaseId)}"`);
161
- }
162
- const sqlRoleSetupCmds = (0, lodash_1.concat)(revokes, [`CREATE SCHEMA IF NOT EXISTS "public"`], ownerRolePermissions(databaseId, superuser, "public"), writerRolePermissions(databaseId, superuser, "public"), readerRolePermissions(databaseId, superuser, "public"));
163
- return (0, connect_1.executeSqlCmdsAsSuperUser)(options, instanceId, databaseId, sqlRoleSetupCmds, silent);
80
+ exports.readerRolePermissions = readerRolePermissions;
81
+ function defaultPermissions(databaseId, schema, ownerRole) {
82
+ const firebaseWriterRole = firebasewriter(databaseId, schema);
83
+ const firebaseReaderRole = firebasereader(databaseId, schema);
84
+ return [
85
+ `ALTER DEFAULT PRIVILEGES
86
+ FOR ROLE "${ownerRole}"
87
+ IN SCHEMA "${schema}"
88
+ GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO "${firebaseWriterRole}";`,
89
+ `ALTER DEFAULT PRIVILEGES
90
+ FOR ROLE "${ownerRole}"
91
+ IN SCHEMA "${schema}"
92
+ GRANT USAGE ON SEQUENCES TO "${firebaseWriterRole}";`,
93
+ `ALTER DEFAULT PRIVILEGES
94
+ FOR ROLE "${ownerRole}"
95
+ IN SCHEMA "${schema}"
96
+ GRANT EXECUTE ON FUNCTIONS TO "${firebaseWriterRole}";`,
97
+ `ALTER DEFAULT PRIVILEGES
98
+ FOR ROLE "${ownerRole}"
99
+ IN SCHEMA "${schema}"
100
+ GRANT SELECT ON TABLES TO "${firebaseReaderRole}";`,
101
+ `ALTER DEFAULT PRIVILEGES
102
+ FOR ROLE "${ownerRole}"
103
+ IN SCHEMA "${schema}"
104
+ GRANT USAGE ON SEQUENCES TO "${firebaseReaderRole}";`,
105
+ `ALTER DEFAULT PRIVILEGES
106
+ FOR ROLE "${ownerRole}"
107
+ IN SCHEMA "${schema}"
108
+ GRANT EXECUTE ON FUNCTIONS TO "${firebaseReaderRole}";`,
109
+ ];
164
110
  }
165
- exports.setupSQLPermissions = setupSQLPermissions;
111
+ exports.defaultPermissions = defaultPermissions;