Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow larger request body in Auth Emulator. Fixes #3570. #3577

Merged
merged 3 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix Auth Emulator errors when importing many users (#3577).
2 changes: 1 addition & 1 deletion scripts/triggers-end-to-end-tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ source scripts/set-default-credentials.sh
npm install
)

mocha \
npx mocha \
--require ts-node/register \
--require source-map-support/register \
--require src/test/helpers/mocha-bootstrap.ts \
Expand Down
84 changes: 83 additions & 1 deletion scripts/triggers-end-to-end-tests/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as path from "path";

import { CLIProcess } from "../integration-helpers/cli";
import { FrameworkOptions, TriggerEndToEndTest } from "../integration-helpers/framework";
import { assert } from "sinon";

const FIREBASE_PROJECT = process.env.FBTOOLS_TARGET_PROJECT || "";
const ADMIN_CREDENTIAL = {
Expand Down Expand Up @@ -518,6 +517,89 @@ describe("import/export end to end", () => {
}
});

it("should be able to import/export auth data with many users", async function (this) {
this.timeout(2 * TEST_SETUP_TIMEOUT);
await new Promise((resolve) => setTimeout(resolve, 2000));

// Start up emulator suite
const project = FIREBASE_PROJECT || "example";
const emulatorsCLI = new CLIProcess("1", __dirname);

await emulatorsCLI.start("emulators:start", project, ["--only", "auth"], (data: unknown) => {
if (typeof data !== "string" && !Buffer.isBuffer(data)) {
throw new Error(`data is not a string or buffer (${typeof data})`);
}
return data.includes(ALL_EMULATORS_STARTED_LOG);
});

// Create some accounts to export:
const accountCount = 777; // ~120KB data when exported
const config = readConfig();
const port = config.emulators!.auth.port;
try {
process.env.FIREBASE_AUTH_EMULATOR_HOST = `localhost:${port}`;
const adminApp = admin.initializeApp(
{
projectId: project,
credential: ADMIN_CREDENTIAL,
},
"admin-app2"
);
for (let i = 0; i < accountCount; i++) {
await adminApp
.auth()
.createUser({ uid: `u${i}`, email: `u${i}@example.com`, password: "testing" });
}
// Ask for export
const exportCLI = new CLIProcess("2", __dirname);
const exportPath = fs.mkdtempSync(path.join(os.tmpdir(), "emulator-data"));
await exportCLI.start("emulators:export", project, [exportPath], (data: unknown) => {
if (typeof data !== "string" && !Buffer.isBuffer(data)) {
throw new Error(`data is not a string or buffer (${typeof data})`);
}
return data.includes("Export complete");
});
await exportCLI.stop();

// Stop the suite
await emulatorsCLI.stop();

// Confirm the data is exported as expected
const configPath = path.join(exportPath, "auth_export", "config.json");
const configData = JSON.parse(fs.readFileSync(configPath).toString());
expect(configData).to.deep.equal({
signIn: {
allowDuplicateEmails: false,
},
});

const accountsPath = path.join(exportPath, "auth_export", "accounts.json");
const accountsData = JSON.parse(fs.readFileSync(accountsPath).toString());
expect(accountsData.users).to.have.length(accountCount);

// Attempt to import
const importCLI = new CLIProcess("3", __dirname);
await importCLI.start(
"emulators:start",
project,
["--only", "auth", "--import", exportPath],
(data: unknown) => {
if (typeof data !== "string" && !Buffer.isBuffer(data)) {
throw new Error(`data is not a string or buffer (${typeof data})`);
}
return data.includes(ALL_EMULATORS_STARTED_LOG);
}
);

// Check users are indeed imported correctly
const user = await adminApp.auth().getUserByEmail(`u${accountCount - 1}@example.com`);
expect(user.passwordHash).to.match(/:password=testing$/);

await importCLI.stop();
} finally {
delete process.env.FIREBASE_AUTH_EMULATOR_HOST;
}
});
it("should be able to export / import auth data with no users", async function (this) {
this.timeout(2 * TEST_SETUP_TIMEOUT);
await new Promise((resolve) => setTimeout(resolve, 2000));
Expand Down
1 change: 1 addition & 0 deletions src/emulator/auth/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export async function createApp(
// Let errors propagate to our universal error handler below.
throw err;
},
defaultMaxBodySize: 1024 * 1024 * 1024, // 1GB instead of the default 10k.
validateDefaultResponses: true,
onResponseValidationError({ errors }) {
logError(
Expand Down