42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
import { randomUUID } from "node:crypto";
|
|
|
|
/**
|
|
* Build the SSO ticket exactly like AtomCMS's User::ssoTicket():
|
|
* $hotelName = Str::replace(' ', '', setting('hotel_name'));
|
|
* sprintf('%s-%s', $hotelName, Str::uuid());
|
|
* i.e. the hotel name with ALL spaces removed, a dash, then a v4 UUID.
|
|
* The emulator validates this exact value when the Nitro/Flash client connects.
|
|
*/
|
|
export function generateSsoTicket(hotelName: string): string {
|
|
const normalized = hotelName.replace(/ /g, "");
|
|
return `${normalized}-${randomUUID()}`;
|
|
}
|
|
|
|
/** Minimal shape of the Prisma client this needs (keeps it unit-testable). */
|
|
export interface SsoUserUpdater {
|
|
user: {
|
|
update(args: {
|
|
where: { id: number };
|
|
data: { authTicket: string; ipCurrent: string };
|
|
}): Promise<unknown>;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Generate a ticket and persist it like AtomCMS: writes auth_ticket AND
|
|
* ip_current on the user, then returns the ticket for the client launcher.
|
|
*/
|
|
export async function issueSsoTicket(
|
|
db: SsoUserUpdater,
|
|
userId: number,
|
|
hotelName: string,
|
|
ip: string,
|
|
): Promise<string> {
|
|
const ticket = generateSsoTicket(hotelName);
|
|
await db.user.update({
|
|
where: { id: userId },
|
|
data: { authTicket: ticket, ipCurrent: ip },
|
|
});
|
|
return ticket;
|
|
}
|