mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
90 lines
3.5 KiB
TypeScript
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();
|
|
}
|
|
})();
|
|
}
|