@wendongfly/myhi 1.3.24 → 1.3.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/daemon.js CHANGED
@@ -93,7 +93,7 @@ async function doUpgrade() {
93
93
  try {
94
94
  const cmd = process.platform === 'win32'
95
95
  ? 'npm.cmd install -g @wendongfly/myhi@latest'
96
- : 'sudo npm install -g @wendongfly/myhi@latest 2>&1 || npm install -g @wendongfly/myhi@latest 2>&1';
96
+ : 'npm install -g @wendongfly/myhi@latest 2>&1 || sudo npm install -g @wendongfly/myhi@latest 2>&1';
97
97
  const output = execSync(cmd, { timeout: 120000, encoding: 'utf8' });
98
98
  log('升级完成: ' + output.trim().split('\n').pop());
99
99
  } catch (e) {
package/bin/myhi.js CHANGED
@@ -683,9 +683,16 @@ SSH 开发:
683
683
  let myhiBin;
684
684
  try { myhiBin = ex('which myhi', { encoding: 'utf8' }).trim(); } catch { myhiBin = '/usr/local/bin/myhi'; }
685
685
 
686
- const user = process.env.USER || 'root';
687
- const home = homedir();
688
- const cwd = process.env.MYHI_CWD || process.cwd();
686
+ // sudo 运行时用 SUDO_USER 获取真实用户
687
+ const user = process.env.SUDO_USER || process.env.USER || 'root';
688
+ let home;
689
+ if (process.env.SUDO_USER) {
690
+ // sudo 时 homedir() 返回 root 的 home,需要查真实用户的 home
691
+ try { home = ex(`getent passwd ${process.env.SUDO_USER}`, { encoding: 'utf8' }).trim().split(':')[5]; } catch { home = `/home/${process.env.SUDO_USER}`; }
692
+ } else {
693
+ home = homedir();
694
+ }
695
+ const cwd = process.env.MYHI_CWD || (process.env.SUDO_USER ? home : process.cwd());
689
696
  const port = process.env.PORT || '12300';
690
697
  const serviceFile = '/etc/systemd/system/myhi.service';
691
698
 
@@ -724,6 +731,21 @@ WantedBy=multi-user.target
724
731
  console.log(` Port: ${port}`);
725
732
  console.log(` WorkingDirectory: ${cwd}`);
726
733
  console.log(` ExecStart: ${myhiBin} -d`);
734
+
735
+ // 配置 sudoers 让服务用户可以自升级和重启
736
+ if (user !== 'root') {
737
+ const sudoersFile = `/etc/sudoers.d/myhi-${user}`;
738
+ const npmBin = (() => { try { return ex('which npm', { encoding: 'utf8' }).trim(); } catch { return '/usr/bin/npm'; } })();
739
+ const sudoersContent = `# myhi: allow ${user} to upgrade and restart service\n${user} ALL=(ALL) NOPASSWD: ${npmBin} install -g @wendongfly/myhi*\n${user} ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myhi.service\n${user} ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop myhi.service\n`;
740
+ try {
741
+ writeFileSync(sudoersFile, sudoersContent, { mode: 0o440 });
742
+ console.log(`[myhi] 已配置 sudoers: ${sudoersFile}`);
743
+ } catch {
744
+ console.log(`[myhi] 提示: 如需 Web 端升级功能,请手动配置 sudoers:`);
745
+ console.log(` echo '${user} ALL=(ALL) NOPASSWD: ${npmBin} install -g @wendongfly/myhi*' | sudo tee ${sudoersFile}`);
746
+ }
747
+ }
748
+
727
749
  console.log('');
728
750
  try {
729
751
  ex('systemctl daemon-reload', { stdio: 'inherit' });
@@ -734,6 +756,7 @@ WantedBy=multi-user.target
734
756
  console.log(' 查看状态: systemctl status myhi.service');
735
757
  console.log(' 查看日志: journalctl -u myhi -f');
736
758
  console.log(' 停止服务: sudo systemctl stop myhi.service');
759
+ console.log(' Web 端升级: 会话页 ⬆ 按钮一键升级');
737
760
  } catch (e) {
738
761
  console.log('[myhi] systemctl 执行失败,请手动运行:');
739
762
  console.log(' sudo systemctl daemon-reload');
@@ -748,6 +771,8 @@ WantedBy=multi-user.target
748
771
  } catch {}
749
772
  try {
750
773
  unlinkSync(serviceFile);
774
+ // 清理 sudoers
775
+ try { unlinkSync(`/etc/sudoers.d/myhi-${user}`); } catch {}
751
776
  ex('systemctl daemon-reload', { stdio: 'pipe' });
752
777
  console.log('[myhi] 已卸载 systemd 服务');
753
778
  } catch (e) {