mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-11 08:42:11 +00:00
Extract the remote-detection helpers (canonicalGitHubRemote, isSshRemote,
isOfficialSshRemote) from main.cjs into a testable update-remote.cjs sibling
module and add a node:test suite, wired into test:desktop:platforms.
main.cjs requires('electron') at load, so its inline helpers weren't unit
testable. The Python side of #43754 shipped a regression test; this gives the
desktop side the same coverage for the security-critical detection that keeps
passive update checks off the SSH origin (avoiding FIDO2/passkey touch
prompts). Tests assert SSH/HTTPS forms canonicalize equal, official SSH is
detected case-insensitively, and forks / other hosts / the HTTPS remote are
NOT misclassified.
56 lines
2 KiB
JavaScript
56 lines
2 KiB
JavaScript
/**
|
|
* Pure helpers for choosing a remote URL during passive update checks.
|
|
*
|
|
* A public install can end up with `origin=git@github.com:NousResearch/hermes-agent.git`.
|
|
* If the user's GitHub SSH key is FIDO2/passkey-backed, a background `git fetch
|
|
* origin` triggers an unexplained hardware-touch prompt. For passive checks
|
|
* against the official repo we substitute the public HTTPS `ls-remote` path,
|
|
* which needs no auth and cannot prompt. Active update/apply flows are left
|
|
* unchanged.
|
|
*
|
|
* Extracted from main.cjs so the security-critical remote detection is unit
|
|
* testable without booting Electron (main.cjs requires('electron') at load).
|
|
*/
|
|
|
|
const OFFICIAL_REPO_HTTPS_URL = 'https://github.com/NousResearch/hermes-agent.git'
|
|
const OFFICIAL_REPO_CANONICAL = 'github.com/nousresearch/hermes-agent'
|
|
|
|
// Normalize common GitHub remote URL forms to `host/owner/repo` (lowercased,
|
|
// no trailing slash, no .git suffix) so SSH and HTTPS forms of the same repo
|
|
// compare equal.
|
|
function canonicalGitHubRemote(url) {
|
|
if (!url) return ''
|
|
let value = String(url).trim()
|
|
if (value.startsWith('git@github.com:')) {
|
|
value = `github.com/${value.slice('git@github.com:'.length)}`
|
|
} else if (value.startsWith('ssh://git@github.com/')) {
|
|
value = `github.com/${value.slice('ssh://git@github.com/'.length)}`
|
|
} else {
|
|
try {
|
|
const parsed = new URL(value)
|
|
if (parsed.hostname && parsed.pathname) value = `${parsed.hostname}${parsed.pathname}`
|
|
} catch {
|
|
// Leave non-URL forms unchanged.
|
|
}
|
|
}
|
|
value = value.trim().replace(/\/+$/, '')
|
|
if (value.endsWith('.git')) value = value.slice(0, -4)
|
|
return value.toLowerCase()
|
|
}
|
|
|
|
function isSshRemote(url) {
|
|
const value = String(url || '').trim().toLowerCase()
|
|
return value.startsWith('git@') || value.startsWith('ssh://')
|
|
}
|
|
|
|
function isOfficialSshRemote(url) {
|
|
return isSshRemote(url) && canonicalGitHubRemote(url) === OFFICIAL_REPO_CANONICAL
|
|
}
|
|
|
|
module.exports = {
|
|
OFFICIAL_REPO_HTTPS_URL,
|
|
OFFICIAL_REPO_CANONICAL,
|
|
canonicalGitHubRemote,
|
|
isSshRemote,
|
|
isOfficialSshRemote
|
|
}
|