73 lines
2.8 KiB
JavaScript
73 lines
2.8 KiB
JavaScript
// mksess-pg.cjs — 临时会话直插工具(PostgreSQL 版)
|
||
//
|
||
// 为什么需要它:仓库里原有的 `mksess.cjs` 仍用 better-sqlite3 打开 `/var/lib/dshs/dshs.db`,
|
||
// 而平台自 2026-09-27 起**只用 PostgreSQL**(本地库文件已改名为 dshs.db.unused-20260927)
|
||
// ⇒ 那个脚本现在**静默无效**(写进一个没人读的文件,退出码仍是 0)。本文件是它的 PG 替代。
|
||
//
|
||
// 用法(在 47 上,root):
|
||
// node mksess-pg.cjs [--ttl-minutes 10] [--role admin]
|
||
// 输出:一行 token(形如 <32字节 hex>)。之后用它当会话 cookie 值:
|
||
// curl -H "Cookie: sid=<token>" http://127.0.0.1:3080/api/...
|
||
// ⛔ 用完请立刻删除该会话(见文件末尾的 revoke 提示)。
|
||
//
|
||
// 边界(R4):⛔ 不用真实账号登录;⛔ 不打印/不落盘任何用户凭据;token 只回显到 stdout。
|
||
|
||
const crypto = require('crypto');
|
||
const fs = require('fs');
|
||
|
||
const CFG = '/opt/dshs/config/platform.env';
|
||
|
||
function arg(name, dflt) {
|
||
const i = process.argv.indexOf(name);
|
||
return i >= 0 && process.argv[i + 1] ? process.argv[i + 1] : dflt;
|
||
}
|
||
|
||
const ttlMinutes = Number(arg('--ttl-minutes', '10'));
|
||
const wantRole = arg('--role', 'admin');
|
||
|
||
// 连接串只在运行时从平台配置读取;⛔ 不打印
|
||
const env = fs.readFileSync(CFG, 'utf8');
|
||
const m = env.match(/^DSHS_DB_URL=(.+)$/m);
|
||
if (!m) {
|
||
console.error('mksess-pg: 平台配置里没有 DSHS_DB_URL');
|
||
process.exit(2);
|
||
}
|
||
const url = m[1].trim();
|
||
|
||
let pg;
|
||
try {
|
||
pg = require('/opt/dshs/node_modules/pg');
|
||
} catch (e) {
|
||
console.error('mksess-pg: 找不到 pg 模块(应从 /opt/dshs 的依赖树加载):', e && e.message);
|
||
process.exit(2);
|
||
}
|
||
|
||
(async () => {
|
||
const client = new pg.Client({ connectionString: url });
|
||
await client.connect();
|
||
try {
|
||
const who = await client.query('select id, username, role from users where role = $1 limit 1', [wantRole]);
|
||
if (who.rowCount === 0) {
|
||
console.error('mksess-pg: 没有 role=' + wantRole + ' 的用户');
|
||
process.exit(3);
|
||
}
|
||
const user = who.rows[0];
|
||
const token = crypto.randomBytes(32).toString('hex');
|
||
const hash = crypto.createHash('sha256').update(token).digest('hex');
|
||
const now = Date.now();
|
||
const exp = now + ttlMinutes * 60 * 1000;
|
||
await client.query(
|
||
'insert into sessions (token_hash, user_id, created_at, expires_at, ip, user_agent) values ($1,$2,$3,$4,$5,$6)',
|
||
[hash, user.id, now, exp, '127.0.0.1', 'mksess-pg'],
|
||
);
|
||
// 只回显 token 与必要元信息;⛔ 不回显连接串
|
||
console.log(token);
|
||
console.error(`mksess-pg: user=${user.username} role=${user.role} ttl=${ttlMinutes}min expires_at=${exp}`);
|
||
} finally {
|
||
await client.end();
|
||
}
|
||
})().catch((e) => {
|
||
console.error('mksess-pg 失败:', e && e.message);
|
||
process.exit(1);
|
||
});
|