GOOD SHELL MAS BOY
Server: Apache/2.4.52 (Ubuntu)
System: Linux vmi1836763.contaboserver.net 5.15.0-130-generic #140-Ubuntu SMP Wed Dec 18 17:59:53 UTC 2024 x86_64
User: www-data (33)
PHP: 8.4.10
Disabled: NONE
Upload Files
File: //usr/local/lib/node_modules/firebase-tools/lib/gcp/cloudsql/connect.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toDatabaseUser = exports.setupIAMUsers = exports.getIAMUser = exports.getDataConnectP4SA = exports.executeSqlCmdsAsSuperUser = exports.executeSqlCmdsAsIamUser = exports.execute = void 0;
const pg = require("pg");
const cloud_sql_connector_1 = require("@google-cloud/cloud-sql-connector");
const requireAuth_1 = require("../../requireAuth");
const projectUtils_1 = require("../../projectUtils");
const api_1 = require("../../api");
const cloudSqlAdminClient = require("./cloudsqladmin");
const utils = require("../../utils");
const logger_1 = require("../../logger");
const error_1 = require("../../error");
const fbToolsAuthClient_1 = require("./fbToolsAuthClient");
const permissions_1 = require("./permissions");
async function execute(sqlStatements, opts) {
    const logFn = opts.silent ? logger_1.logger.debug : logger_1.logger.info;
    const instance = await cloudSqlAdminClient.getInstance(opts.projectId, opts.instanceId);
    const user = await cloudSqlAdminClient.getUser(opts.projectId, opts.instanceId, opts.username);
    const connectionName = instance.connectionName;
    if (!connectionName) {
        throw new error_1.FirebaseError(`Could not get instance connection string for ${opts.instanceId}:${opts.databaseId}`);
    }
    let connector;
    let pool;
    switch (user.type) {
        case "CLOUD_IAM_USER": {
            connector = new cloud_sql_connector_1.Connector({
                auth: new fbToolsAuthClient_1.FBToolsAuthClient(),
            });
            const clientOpts = await connector.getOptions({
                instanceConnectionName: connectionName,
                ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
                authType: cloud_sql_connector_1.AuthTypes.IAM,
            });
            pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, database: opts.databaseId }));
            break;
        }
        case "CLOUD_IAM_SERVICE_ACCOUNT": {
            connector = new cloud_sql_connector_1.Connector();
            const clientOpts = await connector.getOptions({
                instanceConnectionName: connectionName,
                ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
                authType: cloud_sql_connector_1.AuthTypes.IAM,
            });
            pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, database: opts.databaseId }));
            break;
        }
        default: {
            if (!opts.password) {
                throw new error_1.FirebaseError(`Cannot connect as BUILT_IN user without a password.`);
            }
            connector = new cloud_sql_connector_1.Connector({
                auth: new fbToolsAuthClient_1.FBToolsAuthClient(),
            });
            const clientOpts = await connector.getOptions({
                instanceConnectionName: connectionName,
                ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
            });
            pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, password: opts.password, database: opts.databaseId }));
            break;
        }
    }
    const conn = await pool.connect();
    logFn(`Logged in as ${opts.username}`);
    for (const s of sqlStatements) {
        logFn(`Executing: '${s}'`);
        try {
            await conn.query(s);
        }
        catch (err) {
            throw new error_1.FirebaseError(`Error executing ${err}`);
        }
    }
    conn.release();
    await pool.end();
    connector.close();
}
exports.execute = execute;
async function executeSqlCmdsAsIamUser(options, instanceId, databaseId, cmds, silent = false) {
    const projectId = (0, projectUtils_1.needProjectId)(options);
    const { user: iamUser } = await getIAMUser(options);
    return await execute(cmds, {
        projectId,
        instanceId,
        databaseId,
        username: iamUser,
        silent: silent,
    });
}
exports.executeSqlCmdsAsIamUser = executeSqlCmdsAsIamUser;
async function executeSqlCmdsAsSuperUser(options, instanceId, databaseId, cmds, silent = false) {
    const projectId = (0, projectUtils_1.needProjectId)(options);
    const superuser = "firebasesuperuser";
    const temporaryPassword = utils.generateId(20);
    await cloudSqlAdminClient.createUser(projectId, instanceId, "BUILT_IN", superuser, temporaryPassword);
    return await execute([`SET ROLE = cloudsqlsuperuser`, ...cmds], {
        projectId,
        instanceId,
        databaseId,
        username: superuser,
        password: temporaryPassword,
        silent: silent,
    });
}
exports.executeSqlCmdsAsSuperUser = executeSqlCmdsAsSuperUser;
function getDataConnectP4SA(projectNumber) {
    return `service-${projectNumber}@${(0, api_1.dataconnectP4SADomain)()}`;
}
exports.getDataConnectP4SA = getDataConnectP4SA;
async function getIAMUser(options) {
    const account = await (0, requireAuth_1.requireAuth)(options);
    if (!account) {
        throw new error_1.FirebaseError("No account to set up! Run `firebase login` or set Application Default Credentials");
    }
    return toDatabaseUser(account);
}
exports.getIAMUser = getIAMUser;
async function setupIAMUsers(instanceId, databaseId, options) {
    const projectId = (0, projectUtils_1.needProjectId)(options);
    const { user, mode } = await getIAMUser(options);
    await cloudSqlAdminClient.createUser(projectId, instanceId, mode, user);
    const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
    const { user: fdcP4SAUser, mode: fdcP4SAmode } = toDatabaseUser(getDataConnectP4SA(projectNumber));
    await cloudSqlAdminClient.createUser(projectId, instanceId, fdcP4SAmode, fdcP4SAUser);
    await (0, permissions_1.setupSQLPermissions)(instanceId, databaseId, options, true);
    const grants = [
        `GRANT "${(0, permissions_1.firebaseowner)(databaseId)}" TO "${user}"`,
        `GRANT "${(0, permissions_1.firebasewriter)(databaseId)}" TO "${fdcP4SAUser}"`,
    ];
    await executeSqlCmdsAsSuperUser(options, instanceId, databaseId, grants, true);
    return user;
}
exports.setupIAMUsers = setupIAMUsers;
function toDatabaseUser(account) {
    let mode = "CLOUD_IAM_USER";
    let user = account;
    if (account.endsWith(".gserviceaccount.com")) {
        user = account.replace(".gserviceaccount.com", "");
        mode = "CLOUD_IAM_SERVICE_ACCOUNT";
    }
    return { user, mode };
}
exports.toDatabaseUser = toDatabaseUser;