@holdyourvoice/hyv 2.8.9 → 2.8.10

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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable CLI changes. Also mirrored to [holdyourvoice.com/changelog](https://holdyourvoice.com/changelog) for user-facing releases.
4
4
 
5
+ ## [2.8.10] — 2026-06-12
6
+
7
+ ### Fixed
8
+ - `hyv init` browser login opens Google OAuth again (`assertSafeOAuthUrl` allows `accounts.google.com`)
9
+
5
10
  ## [2.8.9] — 2026-06-12
6
11
 
7
12
  ### Improved
package/dist/index.js CHANGED
@@ -4647,6 +4647,27 @@ function assertSafeOpenUrl(url) {
4647
4647
  }
4648
4648
  return url;
4649
4649
  }
4650
+ function assertSafeOAuthUrl(url) {
4651
+ let parsed;
4652
+ try {
4653
+ parsed = new URL(url);
4654
+ } catch {
4655
+ throw new Error("Invalid URL");
4656
+ }
4657
+ if (parsed.protocol !== "https:") {
4658
+ throw new Error("Only https:// URLs can be opened");
4659
+ }
4660
+ if (ALLOWED_API_HOSTS.has(parsed.hostname)) {
4661
+ return url;
4662
+ }
4663
+ if (ALLOWED_OAUTH_HOSTS.has(parsed.hostname)) {
4664
+ if (parsed.hostname === "accounts.google.com" && !parsed.pathname.startsWith("/o/oauth2/")) {
4665
+ throw new Error(`Unexpected OAuth path: ${parsed.pathname}`);
4666
+ }
4667
+ return url;
4668
+ }
4669
+ throw new Error(`URL host not allowed: ${parsed.hostname}`);
4670
+ }
4650
4671
  function assertSafeProfileName(name) {
4651
4672
  const normalized = String(name || "").trim();
4652
4673
  if (!normalized)
@@ -4804,7 +4825,7 @@ function readLastEditSession() {
4804
4825
  return null;
4805
4826
  }
4806
4827
  }
4807
- var fs, path, os, HYV_DIR, AUTH_FILE, CONFIG_FILE, PROFILES_DIR, CACHE_DIR, QUEUE_DIR, LAST_SESSION_FILE, ALLOWED_API_HOSTS, API_BASE, PROFILE_NAME_RE;
4828
+ var fs, path, os, HYV_DIR, AUTH_FILE, CONFIG_FILE, PROFILES_DIR, CACHE_DIR, QUEUE_DIR, LAST_SESSION_FILE, ALLOWED_API_HOSTS, ALLOWED_OAUTH_HOSTS, API_BASE, PROFILE_NAME_RE;
4808
4829
  var init_config = __esm({
4809
4830
  "src/lib/config.ts"() {
4810
4831
  "use strict";
@@ -4825,6 +4846,7 @@ var init_config = __esm({
4825
4846
  "localhost",
4826
4847
  "127.0.0.1"
4827
4848
  ]);
4849
+ ALLOWED_OAUTH_HOSTS = /* @__PURE__ */ new Set(["accounts.google.com"]);
4828
4850
  API_BASE = validateApiBase(process.env.HYV_API_URL || "https://holdyourvoice.com");
4829
4851
  PROFILE_NAME_RE = /^[a-z0-9][a-z0-9._-]{0,62}$/i;
4830
4852
  }
@@ -5392,7 +5414,7 @@ async function authenticateWithBrowser() {
5392
5414
  throw new Error("Authentication server did not return OAuth state");
5393
5415
  }
5394
5416
  console.log(import_chalk.default.cyan("\nOpening browser for authentication..."));
5395
- await (0, import_open.default)(assertSafeOpenUrl(auth_url));
5417
+ await (0, import_open.default)(assertSafeOAuthUrl(auth_url));
5396
5418
  const authData = await new Promise((resolve14, reject) => {
5397
5419
  const timeout = setTimeout(() => {
5398
5420
  server.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holdyourvoice/hyv",
3
- "version": "2.8.9",
3
+ "version": "2.8.10",
4
4
  "description": "Free local AI writing scan for cursor & claude. MCP server, 220+ pattern detection, voice profiles. npx @holdyourvoice/hyv welcome",
5
5
  "main": "dist/index.js",
6
6
  "bin": {