Skip to content

Commit

Permalink
Allow larger request body in Auth Emulator. Fixes #3570. (#3577)
Browse files Browse the repository at this point in the history
* Allow larger request body in Auth Emulator. Fixes #3570.

* CHANGLOG

* Apply suggestions from code review

Co-authored-by: Sam <samgho@google.com>

Co-authored-by: Sam <samgho@google.com>
  • Loading branch information
yuchenshi and sam-gc committed Jul 15, 2021
1 parent 5b56d0f commit f13b644
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
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

0 comments on commit f13b644

Please sign in to comment.