@goodandready/dsh-subscriptions 0.6.63 → 0.6.64

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/README.md CHANGED
@@ -102,6 +102,7 @@ graph LR
102
102
  * **Dynamic Model Catalog & Live Quota Visualizer (#507)**: Dynamic model catalog with pool-level health calculation (individual quarantine degrades rather than disables the pool), context window badges, capability tags (`vision`, `tools`, `reasoning`, `coding`, `fast`), and live reset countdowns.
103
103
  * **Cache-Aware Session Pinning (#520)**: Retains session affinity for prompt-caching providers (Claude, Codex, Antigravity, Grok) to maximize token cache reuse while strictly releasing pins when an account enters cooldown, quarantine, or quota exhaustion.
104
104
  * **Guided Diagnostic Wizard (#519)**: Interactive step-by-step checklist verifying credentials, network/proxy connectivity, token freshness, and model catalog reachability without paid inference and with full secret redaction.
105
+ * **Desktop Electron Compatibility (#524)**: Non-HTTP app schemes (`dsh-app://`) bypass web-only host equality checks while strictly preserving loopback socket verification and fail-closed cross-site protection.
105
106
 
106
107
  ---
107
108
 
package/README.ru.md CHANGED
@@ -102,6 +102,7 @@ graph LR
102
102
  * **Динамический каталог моделей с пуловой доступностью и квотами (#507)**: Обогащенная витрина моделей с расчетом здоровья пула (карантин одного аккаунта не блокирует модель при наличии живых), тегами возможностей (`vision`, `tools`, `reasoning`, `coding`, `fast`), размером контекста и таймером сброса квот.
103
103
  * **Cache-Aware Session Pinning (#520)**: Сохранение привязки сессии к подходящему аккаунту для провайдеров с поддержкой кэширования промптов (Claude, Codex, Antigravity, Grok) с гарантированным немедленным освобождением при кулдауне, карантине или исчерпании квоты.
104
104
  * **Мастер интерактивной диагностики (#519)**: Пошаговый чек-лист состояния аккаунтов (валидность ключей, прокси, токен, доступность каталога) без платного инференса и с автоматическим маскированием секретов.
105
+ * **Совместимость с DSH Desktop (#524)**: Специфичные схемы Electron (`dsh-app://`) пропускаются к проверке loopback-сокета, устраняя ложные блокировки 403 на десктопных клиентах при сохранении полной защиты от cross-site атак.
105
106
 
106
107
  ---
107
108
 
package/lib/http.js CHANGED
@@ -93,13 +93,17 @@ export function isTrustedSettingsRequest(request, targetCtx) {
93
93
  const secFetchSite = String(headers['sec-fetch-site'] || '').toLowerCase()
94
94
  if (secFetchSite === 'cross-site') return false
95
95
 
96
- // 2. If origin header is present, it must match host
96
+ // 2. If origin header is present, verify origin matches host (#524)
97
97
  const host = String(Array.isArray(headers.host) ? headers.host[0] : (headers.host || headers['x-forwarded-host'] || ''))
98
98
  const origin = headers.origin
99
99
  if (origin) {
100
100
  try {
101
101
  const u = new URL(origin)
102
- if (!host || u.host.toLowerCase() !== host.toLowerCase()) {
102
+ if (u.protocol === 'http:' || u.protocol === 'https:') {
103
+ if (!host || u.host.toLowerCase() !== host.toLowerCase()) {
104
+ return false
105
+ }
106
+ } else if (u.protocol !== 'dsh-app:') {
103
107
  return false
104
108
  }
105
109
  } catch {
@@ -107,12 +111,16 @@ export function isTrustedSettingsRequest(request, targetCtx) {
107
111
  }
108
112
  }
109
113
 
110
- // 3. If referer header is present and no origin, referer must match host
114
+ // 3. If referer header is present and no origin, verify http/https referer matches host (#524)
111
115
  const referer = headers.referer
112
116
  if (!origin && referer) {
113
117
  try {
114
118
  const u = new URL(referer)
115
- if (!host || u.host.toLowerCase() !== host.toLowerCase()) {
119
+ if (u.protocol === 'http:' || u.protocol === 'https:') {
120
+ if (!host || u.host.toLowerCase() !== host.toLowerCase()) {
121
+ return false
122
+ }
123
+ } else if (u.protocol !== 'dsh-app:') {
116
124
  return false
117
125
  }
118
126
  } catch {
@@ -166,13 +174,21 @@ export function isTrustedSettingsRequest(request, targetCtx) {
166
174
  if (origin && host) {
167
175
  try {
168
176
  const u = new URL(origin)
169
- if (u.host.toLowerCase() === host.toLowerCase()) return true
177
+ if (u.protocol === 'http:' || u.protocol === 'https:') {
178
+ if (u.host.toLowerCase() === host.toLowerCase()) return true
179
+ } else if (u.protocol === 'dsh-app:') {
180
+ return true
181
+ }
170
182
  } catch { /* bestEffort */ }
171
183
  }
172
184
  if (referer && host) {
173
185
  try {
174
186
  const u = new URL(referer)
175
- if (u.host.toLowerCase() === host.toLowerCase()) return true
187
+ if (u.protocol === 'http:' || u.protocol === 'https:') {
188
+ if (u.host.toLowerCase() === host.toLowerCase()) return true
189
+ } else if (u.protocol === 'dsh-app:') {
190
+ return true
191
+ }
176
192
  } catch { /* bestEffort */ }
177
193
  }
178
194
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-subscriptions",
3
- "version": "0.6.63",
3
+ "version": "0.6.64",
4
4
  "description": "Use ChatGPT Codex, Claude, Grok, Antigravity, Kimi, GLM, Cursor, Kiro, Copilot, Qwen, ERNIE, Spark, JetBrains, Perplexity, Replit, and Cody subscriptions as DeepSeek Harness LLM providers via OAuth.",
5
5
  "license": "MIT",
6
6
  "type": "module",