Skip to content

Commit 22bba8a

Browse files
committed
test(integration): use strong random passwords and harden afterAll
The fake-user generator built passwords as `${email}${randomHash}`, which got flagged by FAPI's compromised-password check (HTTP 422 `form_password_compromised`) and broke the `session-tasks-sign-in-reset-password` E2E flows. Replace it with a high-entropy `fakerPassword()` helper that satisfies default Clerk complexity rules. Also optional-chain the cleanup in `components.test.ts` so a `beforeAll` timeout no longer cascades into a `TypeError` that masks the real failure.
1 parent 61e0a78 commit 22bba8a

4 files changed

Lines changed: 21 additions & 4 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

integration/models/helpers.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ const dedent = (strings: string | Array<string>, ...values: Array<string>) => {
6767

6868
export const hash = () => randomBytes(5).toString('hex');
6969

70+
/**
71+
* Generates a strong, unique password for fake test users.
72+
*
73+
* Avoids any pattern derived from the user's email or other guessable inputs,
74+
* so it doesn't collide with HIBP / compromised-password lists that would
75+
* cause FAPI to reject sign-in with `form_password_compromised` (HTTP 422).
76+
*
77+
* Includes upper, lower, digit, and symbol to satisfy default Clerk password
78+
* complexity rules.
79+
*/
80+
export const fakerPassword = () => {
81+
const bytes = randomBytes(18).toString('base64url');
82+
return `Aa1!${bytes}`;
83+
};
84+
7085
export const waitUntilMessage = async (stream: Readable, message: string) => {
7186
return new Promise<void>(resolve => {
7287
stream.on('data', chunk => {

integration/testUtils/usersService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { APIKey, ClerkClient, Organization, User } from '@clerk/backend';
22
import { faker } from '@faker-js/faker';
33

4-
import { hash } from '../models/helpers';
4+
import { fakerPassword, hash } from '../models/helpers';
55

66
async function withErrorLogging<T>(operation: string, fn: () => Promise<T>): Promise<T> {
77
try {
@@ -133,7 +133,7 @@ export const createUserService = (clerkClient: ClerkClient) => {
133133
lastName: faker.person.lastName(),
134134
email: withEmail ? email : undefined,
135135
username: withUsername ? `${randomHash}_clerk_cookie` : undefined,
136-
password: withPassword ? `${email}${randomHash}` : undefined,
136+
password: withPassword ? fakerPassword() : undefined,
137137
phoneNumber: withPhoneNumber ? phoneNumber : undefined,
138138
deleteIfExists: () => self.deleteIfExists({ email, phoneNumber }),
139139
};

integration/tests/components.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withEmailCodes] })('component
2020

2121
test.afterAll(async () => {
2222
await app.teardown();
23-
await fakeUser.deleteIfExists();
24-
await fakeOrganization.delete();
23+
await fakeUser?.deleteIfExists();
24+
await fakeOrganization?.delete();
2525
});
2626

2727
const components = [

0 commit comments

Comments
 (0)