Files
edr-platform/apps/edr-passenger-api/test/fixtures/seed-passenger-session.ts

90 lines
3.5 KiB
TypeScript

/**
* Seeds a passenger IAM user + session directly (no OTP flow) and mints an access token the portal
* accepts. The API JwtGuard verifies the JWT signature (JWT_ACCESS_TOKEN_SECRET) and looks up the
* session by its `id` claim; the portal then calls /auth/profile which needs a Passenger row linked
* by iamUserId. Returns { token, profile } for the Playwright passenger storageState.
*
* Run standalone to validate: `npx ts-node test/fixtures/seed-passenger-session.ts` (prints the
* token and the /auth/profile status via the running API on :4000).
*/
import { PrismaClient } from "@prisma/client";
import { SignJWT } from "jose";
import { UI_IDS } from "./seed-ui";
export const PASSENGER_USER_ID = "11111111-0000-4000-8000-000000000001";
export const PASSENGER_SESSION_ID = "11111111-0000-4000-8000-000000000002";
const EMAIL = "test.passenger@edr.local";
const USERNAME = "test_passenger";
export async function seedPassengerSession(prisma: PrismaClient): Promise<{ token: string }> {
const secret = process.env.JWT_ACCESS_TOKEN_SECRET;
if (!secret) throw new Error("JWT_ACCESS_TOKEN_SECRET is required to mint the passenger token");
const userInfo = {
id: PASSENGER_USER_ID,
name: { en: "Test Passenger" },
email: EMAIL,
roles: [] as unknown[],
status: "accepted",
employee: [] as unknown[],
userType: "individual",
username: USERNAME,
permissions: [] as unknown[],
};
const expiry = new Date(Date.now() + 7 * 86400_000);
// iam.users (delete-then-insert so re-seeding is idempotent).
await prisma.$executeRawUnsafe(`DELETE FROM iam.sessions WHERE id = $1::uuid`, PASSENGER_SESSION_ID);
await prisma.$executeRawUnsafe(`DELETE FROM iam.users WHERE id = $1::uuid`, PASSENGER_USER_ID);
await prisma.$executeRawUnsafe(
`INSERT INTO iam.users (created_at, id, name, username, email, user_type, status, is_active, has_set_password, is_phone_number_verified, verified_by)
VALUES (now(), $1::uuid, $2::jsonb, $3, $4, 'individual', 'accepted', true, true, true, 'SYSTEM')`,
PASSENGER_USER_ID,
JSON.stringify(userInfo.name),
USERNAME,
EMAIL,
);
await prisma.$executeRawUnsafe(
`INSERT INTO iam.sessions (created_at, id, email, device, "userInfo", expiry_time, refresh_count, status, user_id)
VALUES (now(), $1::uuid, $2, 'e2e', $3::jsonb, $4, 0, 'ACTIVE', $5::uuid)`,
PASSENGER_SESSION_ID,
EMAIL,
JSON.stringify(userInfo),
expiry,
PASSENGER_USER_ID,
);
// Link the seeded Passenger row to this IAM user so /auth/profile resolves.
await prisma.passenger.update({
where: { id: UI_IDS.passenger },
data: { iamUserId: PASSENGER_USER_ID },
});
const token = await new SignJWT({ id: PASSENGER_SESSION_ID })
.setProtectedHeader({ alg: "HS256", typ: "JWT" })
.setIssuedAt()
.setExpirationTime("7d")
.sign(new TextEncoder().encode(secret));
return { token };
}
if (require.main === module) {
(async () => {
const prisma = new PrismaClient();
try {
const { token } = await seedPassengerSession(prisma);
const api = process.env.API_URL ?? "http://localhost:4000";
const res = await fetch(`${api}/auth/profile`, {
headers: { Authorization: `Bearer ${token}` },
});
// eslint-disable-next-line no-console
console.log(`[passenger-session] /auth/profile -> HTTP ${res.status}`);
// eslint-disable-next-line no-console
console.log((await res.text()).slice(0, 400));
} finally {
await prisma.$disconnect();
}
})();
}