Tabs is better for this yay Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
56 lines
2.6 KiB
JavaScript
56 lines
2.6 KiB
JavaScript
const jwt = require('jsonwebtoken');
|
|
const crypto = require('crypto');
|
|
const { APP_URL, JWT_REFRESH_SECRET, USERS } = require('./env');
|
|
const { sequelize, getUserIdByEmail, getPendingOtp } = require('./db');
|
|
|
|
/** Build the cookie jar for context.addCookies() from a refresh token. */
|
|
function buildCookies(refreshToken, csrfToken = 'e2e-csrf') {
|
|
return [
|
|
{ name: 'refreshToken', value: refreshToken, domain: 'localhost', path: '/', httpOnly: true, secure: false, sameSite: 'Lax' },
|
|
{ name: 'csrfToken', value: csrfToken, domain: 'localhost', path: '/', httpOnly: false, secure: false, sameSite: 'Lax' },
|
|
{ name: 'sidebar_state', value: 'false', domain: 'localhost', path: '/', httpOnly: false, secure: false, sameSite: 'Lax' },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Generate a fresh refresh token + DB session row for a client user, keyed
|
|
* by email (not a hardcoded user_id — those drift as test accounts get
|
|
* recreated, see chibistar/automation/starr/config.cjs history).
|
|
*/
|
|
async function generateClientSession(email) {
|
|
const user_id = await getUserIdByEmail(email);
|
|
const refreshToken = jwt.sign({ user_id }, JWT_REFRESH_SECRET, { expiresIn: '7d' });
|
|
const tokenHash = crypto.createHash('sha256').update(refreshToken).digest('hex');
|
|
|
|
await sequelize.query(
|
|
`INSERT INTO user_sessions (user_id, refresh_token_hash, is_active, login_info, "createdAt", "updatedAt")
|
|
VALUES (:uid, :hash, true, '{}', NOW(), NOW())`,
|
|
{ replacements: { uid: user_id, hash: tokenHash }, type: sequelize.QueryTypes.INSERT },
|
|
);
|
|
|
|
return { user_id, refreshToken };
|
|
}
|
|
|
|
/**
|
|
* Authenticate as admin via cookie injection (same mechanism as
|
|
* generateClientSession), not the UI login form.
|
|
*
|
|
* REAL FINDING (2026-08-25): the admin account (k80308392@gmail.com) is
|
|
* Google-OAuth-only now — submitting the UI email/password form returns
|
|
* "Login failed — Please log in with Google." This matches a prior finding
|
|
* that the *live*-domain admin session had gone Google-only, but it turns
|
|
* out to be true here against localhost too, so the email+password+OTP flow
|
|
* this helper originally ported from chibistar/automation/starr/config.cjs
|
|
* (loginAsAdmin) is dead — forging the session cookie is the only way in now.
|
|
*/
|
|
async function loginAsAdmin(page) {
|
|
const { refreshToken } = await generateClientSession(USERS.admin.email);
|
|
await page.context().addCookies(buildCookies(refreshToken));
|
|
await page.goto(`${APP_URL}/admin`, { waitUntil: 'networkidle' });
|
|
if (/\/login/.test(page.url())) {
|
|
throw new Error('Cookie-based admin auth bounced to /login — check JWT_REFRESH_SECRET / user_sessions wiring.');
|
|
}
|
|
}
|
|
|
|
module.exports = { buildCookies, generateClientSession, loginAsAdmin };
|