@camstack/addon-provider-bosch 0.1.42 → 0.1.44

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.
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_bosch_instances = require("../bosch-instances-CINVxMF_.js");
3
- const require_account_integration_offline = require("../account-integration-offline-D2xBMGsR.js");
2
+ const require_bosch_instances = require("../bosch-instances-CXMUquuA.js");
3
+ const require_account_integration_offline = require("../account-integration-offline-CFyuKmsG.js");
4
4
  let node_crypto = require("node:crypto");
5
5
  let node_tls = require("node:tls");
6
6
  let node_zlib = require("node:zlib");
@@ -31,23 +31,6 @@ var homeConnectActions = require_bosch_instances.defineCustomActions({
31
31
  kind: "mutation",
32
32
  auth: "admin"
33
33
  }),
34
- /**
35
- * The form asks while the proxied login page is open: `pending` until the hub captured the
36
- * app-scheme redirect and finished the exchange, then the same fields `finishSignIn` returns.
37
- * Claimed once. A failed exchange answers with its operator-facing message as an error.
38
- */
39
- claimSignIn: require_bosch_instances.customAction(require_bosch_instances.object({ attemptId: require_bosch_instances.string().min(1) }), require_bosch_instances.object({
40
- pending: require_bosch_instances.boolean(),
41
- token: require_bosch_instances.string().optional().meta({ secret: true }),
42
- refresh: require_bosch_instances.string().optional().meta({ secret: true }),
43
- accountLabel: require_bosch_instances.string().optional(),
44
- appliances: require_bosch_instances.string().optional(),
45
- applianceSecrets: require_bosch_instances.string().optional().meta({ secret: true }),
46
- summary: require_bosch_instances.string().optional()
47
- }), {
48
- kind: "mutation",
49
- auth: "admin"
50
- }),
51
34
  signOut: require_bosch_instances.customAction(require_bosch_instances.object({}), require_bosch_instances.object({
52
35
  signedOut: require_bosch_instances.literal(true),
53
36
  summary: require_bosch_instances.string()
@@ -628,11 +611,10 @@ var HOME_CONNECT_IDDF_URL = (haId) => `https://eu.services.home-connect.com/api/
628
611
  var HOME_CONNECT_CLIENT_ID = "9B75AC9EC512F36C84256AC47D813E2C1DD0D6520DF774B020E1E6E2EB29B1F3";
629
612
  var HOME_CONNECT_OAUTH_BASE = "https://api.home-connect.com/security/oauth/";
630
613
  var ASSET_BASE = "https://eu.services.home-connect.com/";
631
- var HOME_CONNECT_REDIRECT_URI = "hcauth://auth/prod";
632
614
  var HOME_CONNECT_AUTHORIZE_SCOPE = "Control DeleteAppliance IdentifyAppliance Images Monitor ReadAccount ReadOrigApi Settings WriteAppliance WriteOrigApi";
633
615
  var APP_ID$1 = HOME_CONNECT_CLIENT_ID;
634
616
  var OAUTH_BASE = HOME_CONNECT_OAUTH_BASE;
635
- var REDIRECT_URI = HOME_CONNECT_REDIRECT_URI;
617
+ var REDIRECT_URI = require_account_integration_offline.HOME_CONNECT_REDIRECT_URI;
636
618
  var AUTHORIZE_SCOPE = HOME_CONNECT_AUTHORIZE_SCOPE;
637
619
  var CookieJar = class {
638
620
  #cookies = /* @__PURE__ */ new Map();
@@ -1230,6 +1212,12 @@ function sameHomeConnectConnection(a, b) {
1230
1212
  }
1231
1213
  /** Sentinel so the gateway fields stay filled by sign-in and stay off the form. */
1232
1214
  var HOME_CONNECT_PAIRED_ONLY = "__paired_only__";
1215
+ var HOME_CONNECT_SIGN_IN_GUIDE = {
1216
+ i18nPrefix: "home-connect.s_gateway",
1217
+ keyPrefix: "__home-connect",
1218
+ providerName: "Home Connect",
1219
+ redirectStart: `${require_account_integration_offline.HOME_CONNECT_REDIRECT_URI}?code=`
1220
+ };
1233
1221
  function buildHomeConnectFormSchema() {
1234
1222
  const pairedOnly = {
1235
1223
  field: "__hidden__",
@@ -1239,10 +1227,11 @@ function buildHomeConnectFormSchema() {
1239
1227
  id: "gateway",
1240
1228
  title: "Home Connect",
1241
1229
  titleKey: "provider-bosch:home-connect.s_gateway.title",
1242
- description: "Sign in with your Home Connect account. A new tab opens the sign-in page through this hub and finishes on its own.",
1230
+ description: "Sign in with your Home Connect account in your own browser, then paste the address the browser stops on.",
1243
1231
  descriptionKey: "provider-bosch:home-connect.s_gateway.description",
1244
1232
  columns: 1,
1245
1233
  fields: [
1234
+ ...require_account_integration_offline.buildSignInGuideFields(HOME_CONNECT_SIGN_IN_GUIDE),
1246
1235
  {
1247
1236
  type: "account-sign-in",
1248
1237
  addonId: "bosch-home-connect",
@@ -1252,7 +1241,6 @@ function buildHomeConnectFormSchema() {
1252
1241
  providerLabel: "Home Connect",
1253
1242
  beginAction: "beginSignIn",
1254
1243
  completeAction: "finishSignIn",
1255
- claimAction: "claimSignIn",
1256
1244
  signOutAction: "signOut",
1257
1245
  accountKey: "accountLabel",
1258
1246
  countFromKey: "appliances",
@@ -1404,46 +1392,6 @@ function homeConnectFinishResult(account) {
1404
1392
  };
1405
1393
  }
1406
1394
  //#endregion
1407
- //#region src/home-connect/home-connect-sign-in-proxy.ts
1408
- /**
1409
- * Home Connect signs in through its own identity pages, which end on `hcauth://auth/prod?...`
1410
- * — an address no browser can open. These are the hosts those pages are served from; the
1411
- * proxy reaches nothing else. The authorize call redirects to SingleKey ID, whose page loads its
1412
- * scripts from `cdn.singlekey-id.com` (see `HOMECOM_LOGIN_HOSTS`).
1413
- */
1414
- var HOME_CONNECT_LOGIN_HOSTS = [
1415
- "api.home-connect.com",
1416
- "singlekey-id.com",
1417
- "cdn.singlekey-id.com"
1418
- ];
1419
- var HOME_CONNECT_APP_SCHEME = HOME_CONNECT_REDIRECT_URI.slice(0, HOME_CONNECT_REDIRECT_URI.indexOf("://") + 3);
1420
- var homeConnectSignInClaims = require_account_integration_offline.createSignInClaims();
1421
- /** Start an attempt whose `authorizeUrl` is the hub-relative proxied login page. */
1422
- function beginHomeConnectProxiedSignIn(deps) {
1423
- const nowMs = deps.nowMs ?? (() => Date.now());
1424
- const published = publishHomeConnectSignIn(homeConnectSignInAttempts, nowMs());
1425
- if (deps.proxy === null) return published;
1426
- const entry = require_account_integration_offline.openSignInProxy({
1427
- proxy: deps.proxy,
1428
- claims: homeConnectSignInClaims,
1429
- addonId: deps.addonId,
1430
- attemptId: published.attemptId,
1431
- authorizeUrl: published.authorizeUrl,
1432
- hosts: HOME_CONNECT_LOGIN_HOSTS,
1433
- appScheme: HOME_CONNECT_APP_SCHEME,
1434
- finish: async (callback) => homeConnectFinishResult(await finishHomeConnectSignIn({
1435
- attemptId: published.attemptId,
1436
- callback,
1437
- nowMs: nowMs()
1438
- }, homeConnectSignInAttempts, deps.fetchImpl)),
1439
- nowMs
1440
- });
1441
- return {
1442
- attemptId: published.attemptId,
1443
- authorizeUrl: entry
1444
- };
1445
- }
1446
- //#endregion
1447
1395
  //#region src/home-connect/home-connect-discovery.ts
1448
1396
  /** Dishwasher accessory label: `Dishwasher` plus the appliance name. */
1449
1397
  function homeConnectDishwasherEntityName(containerName) {
@@ -5337,7 +5285,13 @@ function buildHomeConnectInstances(records, deps) {
5337
5285
  role: "devices",
5338
5286
  instanceMode: "multiple",
5339
5287
  kind: "account",
5340
- canTest: true
5288
+ canTest: true,
5289
+ kinds: [{
5290
+ id: "connection",
5291
+ label: "Bosch Home Connect",
5292
+ functionCap: "device-provider",
5293
+ role: "devices"
5294
+ }]
5341
5295
  },
5342
5296
  formSchema: () => buildHomeConnectFormSchema(),
5343
5297
  initialBody: (name) => ({ name }),
@@ -5372,8 +5326,6 @@ var BoschHomeConnectProviderAddon = class extends require_bosch_instances.BaseDe
5372
5326
  clients = null;
5373
5327
  instances = null;
5374
5328
  reconciler = null;
5375
- loginProxy = null;
5376
- loginPlane = null;
5377
5329
  constructor() {
5378
5330
  super({});
5379
5331
  }
@@ -5392,7 +5344,6 @@ var BoschHomeConnectProviderAddon = class extends require_bosch_instances.BaseDe
5392
5344
  tester: this.buildConnectionTestProvider()
5393
5345
  });
5394
5346
  this.instances = built;
5395
- await this.serveLoginProxy();
5396
5347
  this.clients = new HomeConnectClientRegistry(this.ctx.logger, { onConnectionUpdated: (integrationId, connection) => {
5397
5348
  this.persistIntegrationAppliances(integrationId, connection);
5398
5349
  } });
@@ -5422,24 +5373,14 @@ var BoschHomeConnectProviderAddon = class extends require_bosch_instances.BaseDe
5422
5373
  customActions: homeConnectActions,
5423
5374
  actionHandlers: {
5424
5375
  beginSignIn: async () => ({
5425
- ...beginHomeConnectProxiedSignIn({
5426
- proxy: this.loginProxy,
5427
- addonId: this.ctx.id
5428
- }),
5429
- summary: "Open the sign-in page and sign in."
5376
+ ...publishHomeConnectSignIn(homeConnectSignInAttempts, Date.now()),
5377
+ summary: "Open the sign-in page, sign in, then paste the address the browser stops on."
5430
5378
  }),
5431
5379
  finishSignIn: async (input) => homeConnectFinishResult(await finishHomeConnectSignIn({
5432
5380
  attemptId: input.attemptId,
5433
5381
  callback: input.callback,
5434
5382
  nowMs: Date.now()
5435
5383
  }, homeConnectSignInAttempts)),
5436
- claimSignIn: async (input) => {
5437
- const claim = homeConnectSignInClaims.claim(input.attemptId, Date.now());
5438
- return claim.state === "pending" ? { pending: true } : {
5439
- pending: false,
5440
- ...claim.result
5441
- };
5442
- },
5443
5384
  signOut: async () => ({
5444
5385
  signedOut: true,
5445
5386
  summary: "Signed out."
@@ -5447,27 +5388,7 @@ var BoschHomeConnectProviderAddon = class extends require_bosch_instances.BaseDe
5447
5388
  }
5448
5389
  };
5449
5390
  }
5450
- /** The hub's HTTPS face for the vendor's login pages (D955): admin session only. */
5451
- async serveLoginProxy() {
5452
- const proxy = new require_bosch_instances.VendorLoginProxy({
5453
- addonId: this.ctx.id,
5454
- logger: this.ctx.logger
5455
- });
5456
- try {
5457
- this.loginPlane = await this.ctx.dataPlane?.serve({
5458
- prefix: "vendor-login",
5459
- access: "admin",
5460
- handler: proxy.handler
5461
- }) ?? null;
5462
- if (this.loginPlane !== null) this.loginProxy = proxy;
5463
- } catch (err) {
5464
- this.ctx.logger.warn("Home Connect login proxy failed to serve — sign-in falls back to paste", { meta: { error: require_bosch_instances.errMsg(err) } });
5465
- }
5466
- }
5467
5391
  async onShutdown() {
5468
- await this.loginPlane?.dispose().catch(() => void 0);
5469
- this.loginPlane = null;
5470
- this.loginProxy = null;
5471
5392
  this.reconciler?.stop();
5472
5393
  this.reconciler = null;
5473
5394
  try {
@@ -1,5 +1,5 @@
1
- import { A as RecordIntegrationInstances, B as array, C as powerMeterCapability, E as runningStateCapability, F as entryBody, G as record, H as literal, I as isSecretMarker, J as unknown, K as string, L as isSecretMarkerLike, M as customAction, N as defineCustomActions, P as defineEntryKind, Q as EventCategory, R as rowsDepsOver, S as numericSensorCapability, T as runningFromDishwasherOperation, V as boolean, W as object, X as DeviceType, Y as DeviceRole, Z as errMsg, _ as enumSensorCapability, a as BaseDevice, b as ingestReading, c as RUNNING_STATE_COLD, f as binaryCapability, g as dishwasherCapability, h as deviceAdoptionCapability, i as testBoschInstance, j as createEvent, m as consumablesCapability, n as boschRowsPorts, o as BaseDeviceProvider, q as union, r as keepBodyKeys, s as DishwasherOperationStateSchema, t as boschRowsMigration, u as VendorLoginProxy, v as eventEmitterCapability, w as quantityFromUnit, x as integrationInstancesCapability, z as _enum } from "../bosch-instances-BmvHlGiY.mjs";
2
- import { a as createSignInAttemptStore, i as openSignInProxy, n as cascadeRemoveDevicesForIntegration, o as loginFailureForAttempt, r as createSignInClaims, s as parseOAuthCallback, t as setIntegrationDevicesOnline } from "../account-integration-offline-cC99EePp.mjs";
1
+ import { A as customAction, C as runningFromDishwasherOperation, F as isSecretMarkerLike, G as unknown, H as record, I as rowsDepsOver, J as errMsg, K as DeviceRole, L as _enum, M as defineEntryKind, N as entryBody, O as RecordIntegrationInstances, P as isSecretMarker, R as array, S as quantityFromUnit, U as string, V as object, W as union, Y as EventCategory, a as BaseDevice, b as numericSensorCapability, c as RUNNING_STATE_COLD, f as consumablesCapability, g as eventEmitterCapability, h as enumSensorCapability, i as testBoschInstance, j as defineCustomActions, k as createEvent, m as dishwasherCapability, n as boschRowsPorts, o as BaseDeviceProvider, p as deviceAdoptionCapability, q as DeviceType, r as keepBodyKeys, s as DishwasherOperationStateSchema, t as boschRowsMigration, u as binaryCapability, v as ingestReading, w as runningStateCapability, x as powerMeterCapability, y as integrationInstancesCapability, z as literal } from "../bosch-instances-C8FRjQzC.mjs";
2
+ import { a as loginFailureForAttempt, c as HOME_CONNECT_REDIRECT_URI, i as createSignInAttemptStore, n as cascadeRemoveDevicesForIntegration, o as parseOAuthCallback, r as buildSignInGuideFields, t as setIntegrationDevicesOnline } from "../account-integration-offline-IHodWmhD.mjs";
3
3
  import { createHash, randomBytes } from "node:crypto";
4
4
  import { connect } from "node:tls";
5
5
  import { inflateRawSync } from "node:zlib";
@@ -30,23 +30,6 @@ var homeConnectActions = defineCustomActions({
30
30
  kind: "mutation",
31
31
  auth: "admin"
32
32
  }),
33
- /**
34
- * The form asks while the proxied login page is open: `pending` until the hub captured the
35
- * app-scheme redirect and finished the exchange, then the same fields `finishSignIn` returns.
36
- * Claimed once. A failed exchange answers with its operator-facing message as an error.
37
- */
38
- claimSignIn: customAction(object({ attemptId: string().min(1) }), object({
39
- pending: boolean(),
40
- token: string().optional().meta({ secret: true }),
41
- refresh: string().optional().meta({ secret: true }),
42
- accountLabel: string().optional(),
43
- appliances: string().optional(),
44
- applianceSecrets: string().optional().meta({ secret: true }),
45
- summary: string().optional()
46
- }), {
47
- kind: "mutation",
48
- auth: "admin"
49
- }),
50
33
  signOut: customAction(object({}), object({
51
34
  signedOut: literal(true),
52
35
  summary: string()
@@ -627,7 +610,6 @@ var HOME_CONNECT_IDDF_URL = (haId) => `https://eu.services.home-connect.com/api/
627
610
  var HOME_CONNECT_CLIENT_ID = "9B75AC9EC512F36C84256AC47D813E2C1DD0D6520DF774B020E1E6E2EB29B1F3";
628
611
  var HOME_CONNECT_OAUTH_BASE = "https://api.home-connect.com/security/oauth/";
629
612
  var ASSET_BASE = "https://eu.services.home-connect.com/";
630
- var HOME_CONNECT_REDIRECT_URI = "hcauth://auth/prod";
631
613
  var HOME_CONNECT_AUTHORIZE_SCOPE = "Control DeleteAppliance IdentifyAppliance Images Monitor ReadAccount ReadOrigApi Settings WriteAppliance WriteOrigApi";
632
614
  var APP_ID$1 = HOME_CONNECT_CLIENT_ID;
633
615
  var OAUTH_BASE = HOME_CONNECT_OAUTH_BASE;
@@ -1229,6 +1211,12 @@ function sameHomeConnectConnection(a, b) {
1229
1211
  }
1230
1212
  /** Sentinel so the gateway fields stay filled by sign-in and stay off the form. */
1231
1213
  var HOME_CONNECT_PAIRED_ONLY = "__paired_only__";
1214
+ var HOME_CONNECT_SIGN_IN_GUIDE = {
1215
+ i18nPrefix: "home-connect.s_gateway",
1216
+ keyPrefix: "__home-connect",
1217
+ providerName: "Home Connect",
1218
+ redirectStart: `${HOME_CONNECT_REDIRECT_URI}?code=`
1219
+ };
1232
1220
  function buildHomeConnectFormSchema() {
1233
1221
  const pairedOnly = {
1234
1222
  field: "__hidden__",
@@ -1238,10 +1226,11 @@ function buildHomeConnectFormSchema() {
1238
1226
  id: "gateway",
1239
1227
  title: "Home Connect",
1240
1228
  titleKey: "provider-bosch:home-connect.s_gateway.title",
1241
- description: "Sign in with your Home Connect account. A new tab opens the sign-in page through this hub and finishes on its own.",
1229
+ description: "Sign in with your Home Connect account in your own browser, then paste the address the browser stops on.",
1242
1230
  descriptionKey: "provider-bosch:home-connect.s_gateway.description",
1243
1231
  columns: 1,
1244
1232
  fields: [
1233
+ ...buildSignInGuideFields(HOME_CONNECT_SIGN_IN_GUIDE),
1245
1234
  {
1246
1235
  type: "account-sign-in",
1247
1236
  addonId: "bosch-home-connect",
@@ -1251,7 +1240,6 @@ function buildHomeConnectFormSchema() {
1251
1240
  providerLabel: "Home Connect",
1252
1241
  beginAction: "beginSignIn",
1253
1242
  completeAction: "finishSignIn",
1254
- claimAction: "claimSignIn",
1255
1243
  signOutAction: "signOut",
1256
1244
  accountKey: "accountLabel",
1257
1245
  countFromKey: "appliances",
@@ -1403,46 +1391,6 @@ function homeConnectFinishResult(account) {
1403
1391
  };
1404
1392
  }
1405
1393
  //#endregion
1406
- //#region src/home-connect/home-connect-sign-in-proxy.ts
1407
- /**
1408
- * Home Connect signs in through its own identity pages, which end on `hcauth://auth/prod?...`
1409
- * — an address no browser can open. These are the hosts those pages are served from; the
1410
- * proxy reaches nothing else. The authorize call redirects to SingleKey ID, whose page loads its
1411
- * scripts from `cdn.singlekey-id.com` (see `HOMECOM_LOGIN_HOSTS`).
1412
- */
1413
- var HOME_CONNECT_LOGIN_HOSTS = [
1414
- "api.home-connect.com",
1415
- "singlekey-id.com",
1416
- "cdn.singlekey-id.com"
1417
- ];
1418
- var HOME_CONNECT_APP_SCHEME = HOME_CONNECT_REDIRECT_URI.slice(0, HOME_CONNECT_REDIRECT_URI.indexOf("://") + 3);
1419
- var homeConnectSignInClaims = createSignInClaims();
1420
- /** Start an attempt whose `authorizeUrl` is the hub-relative proxied login page. */
1421
- function beginHomeConnectProxiedSignIn(deps) {
1422
- const nowMs = deps.nowMs ?? (() => Date.now());
1423
- const published = publishHomeConnectSignIn(homeConnectSignInAttempts, nowMs());
1424
- if (deps.proxy === null) return published;
1425
- const entry = openSignInProxy({
1426
- proxy: deps.proxy,
1427
- claims: homeConnectSignInClaims,
1428
- addonId: deps.addonId,
1429
- attemptId: published.attemptId,
1430
- authorizeUrl: published.authorizeUrl,
1431
- hosts: HOME_CONNECT_LOGIN_HOSTS,
1432
- appScheme: HOME_CONNECT_APP_SCHEME,
1433
- finish: async (callback) => homeConnectFinishResult(await finishHomeConnectSignIn({
1434
- attemptId: published.attemptId,
1435
- callback,
1436
- nowMs: nowMs()
1437
- }, homeConnectSignInAttempts, deps.fetchImpl)),
1438
- nowMs
1439
- });
1440
- return {
1441
- attemptId: published.attemptId,
1442
- authorizeUrl: entry
1443
- };
1444
- }
1445
- //#endregion
1446
1394
  //#region src/home-connect/home-connect-discovery.ts
1447
1395
  /** Dishwasher accessory label: `Dishwasher` plus the appliance name. */
1448
1396
  function homeConnectDishwasherEntityName(containerName) {
@@ -5336,7 +5284,13 @@ function buildHomeConnectInstances(records, deps) {
5336
5284
  role: "devices",
5337
5285
  instanceMode: "multiple",
5338
5286
  kind: "account",
5339
- canTest: true
5287
+ canTest: true,
5288
+ kinds: [{
5289
+ id: "connection",
5290
+ label: "Bosch Home Connect",
5291
+ functionCap: "device-provider",
5292
+ role: "devices"
5293
+ }]
5340
5294
  },
5341
5295
  formSchema: () => buildHomeConnectFormSchema(),
5342
5296
  initialBody: (name) => ({ name }),
@@ -5371,8 +5325,6 @@ var BoschHomeConnectProviderAddon = class extends BaseDeviceProvider {
5371
5325
  clients = null;
5372
5326
  instances = null;
5373
5327
  reconciler = null;
5374
- loginProxy = null;
5375
- loginPlane = null;
5376
5328
  constructor() {
5377
5329
  super({});
5378
5330
  }
@@ -5391,7 +5343,6 @@ var BoschHomeConnectProviderAddon = class extends BaseDeviceProvider {
5391
5343
  tester: this.buildConnectionTestProvider()
5392
5344
  });
5393
5345
  this.instances = built;
5394
- await this.serveLoginProxy();
5395
5346
  this.clients = new HomeConnectClientRegistry(this.ctx.logger, { onConnectionUpdated: (integrationId, connection) => {
5396
5347
  this.persistIntegrationAppliances(integrationId, connection);
5397
5348
  } });
@@ -5421,24 +5372,14 @@ var BoschHomeConnectProviderAddon = class extends BaseDeviceProvider {
5421
5372
  customActions: homeConnectActions,
5422
5373
  actionHandlers: {
5423
5374
  beginSignIn: async () => ({
5424
- ...beginHomeConnectProxiedSignIn({
5425
- proxy: this.loginProxy,
5426
- addonId: this.ctx.id
5427
- }),
5428
- summary: "Open the sign-in page and sign in."
5375
+ ...publishHomeConnectSignIn(homeConnectSignInAttempts, Date.now()),
5376
+ summary: "Open the sign-in page, sign in, then paste the address the browser stops on."
5429
5377
  }),
5430
5378
  finishSignIn: async (input) => homeConnectFinishResult(await finishHomeConnectSignIn({
5431
5379
  attemptId: input.attemptId,
5432
5380
  callback: input.callback,
5433
5381
  nowMs: Date.now()
5434
5382
  }, homeConnectSignInAttempts)),
5435
- claimSignIn: async (input) => {
5436
- const claim = homeConnectSignInClaims.claim(input.attemptId, Date.now());
5437
- return claim.state === "pending" ? { pending: true } : {
5438
- pending: false,
5439
- ...claim.result
5440
- };
5441
- },
5442
5383
  signOut: async () => ({
5443
5384
  signedOut: true,
5444
5385
  summary: "Signed out."
@@ -5446,27 +5387,7 @@ var BoschHomeConnectProviderAddon = class extends BaseDeviceProvider {
5446
5387
  }
5447
5388
  };
5448
5389
  }
5449
- /** The hub's HTTPS face for the vendor's login pages (D955): admin session only. */
5450
- async serveLoginProxy() {
5451
- const proxy = new VendorLoginProxy({
5452
- addonId: this.ctx.id,
5453
- logger: this.ctx.logger
5454
- });
5455
- try {
5456
- this.loginPlane = await this.ctx.dataPlane?.serve({
5457
- prefix: "vendor-login",
5458
- access: "admin",
5459
- handler: proxy.handler
5460
- }) ?? null;
5461
- if (this.loginPlane !== null) this.loginProxy = proxy;
5462
- } catch (err) {
5463
- this.ctx.logger.warn("Home Connect login proxy failed to serve — sign-in falls back to paste", { meta: { error: errMsg(err) } });
5464
- }
5465
- }
5466
5390
  async onShutdown() {
5467
- await this.loginPlane?.dispose().catch(() => void 0);
5468
- this.loginPlane = null;
5469
- this.loginProxy = null;
5470
5391
  this.reconciler?.stop();
5471
5392
  this.reconciler = null;
5472
5393
  try {
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_bosch_instances = require("../bosch-instances-CINVxMF_.js");
3
- const require_account_integration_offline = require("../account-integration-offline-D2xBMGsR.js");
2
+ const require_bosch_instances = require("../bosch-instances-CXMUquuA.js");
3
+ const require_account_integration_offline = require("../account-integration-offline-CFyuKmsG.js");
4
4
  let node_crypto = require("node:crypto");
5
5
  //#region src/homecom/config.ts
6
6
  var HOMECOM_BRANDS = ["bosch", "buderus"];
@@ -46,23 +46,22 @@ var HIDDEN_UNTIL_ADVANCED = {
46
46
  field: "__hidden__",
47
47
  equals: "yes"
48
48
  };
49
- var HOMECOM_CODE_HELP = "If the page does not finish, copy the address it stops on (it starts with com.bosch.tt.dashtt.pointt://app/login?code=) or only the code, and paste it in the box under the sign-in button.";
49
+ var HOMECOM_SIGN_IN_GUIDE = {
50
+ i18nPrefix: "homecom.s_account",
51
+ keyPrefix: "__homecom",
52
+ providerName: "SingleKey ID",
53
+ redirectStart: `${require_account_integration_offline.HOMECOM_REDIRECT_URI}?code=`
54
+ };
50
55
  function buildHomeComFormSchema() {
51
56
  return { sections: [{
52
57
  id: "account",
53
58
  title: "HomeCom account",
54
59
  titleKey: "provider-bosch:homecom.s_account.title",
55
- description: "Sign in with your SingleKey ID. A new tab opens the sign-in page through this hub and finishes on its own.",
60
+ description: "Sign in with your SingleKey ID in your own browser, then paste the address the browser stops on.",
56
61
  descriptionKey: "provider-bosch:homecom.s_account.description",
57
62
  columns: 1,
58
63
  fields: [
59
- {
60
- type: "info",
61
- key: "__homecom-code-help",
62
- label: HOMECOM_CODE_HELP,
63
- labelKey: "provider-bosch:homecom.s_account.__homecom-code-help.label",
64
- content: ""
65
- },
64
+ ...require_account_integration_offline.buildSignInGuideFields(HOMECOM_SIGN_IN_GUIDE),
66
65
  {
67
66
  type: "account-sign-in",
68
67
  addonId: "bosch-homecom",
@@ -72,7 +71,6 @@ function buildHomeComFormSchema() {
72
71
  providerLabel: "SingleKey ID",
73
72
  beginAction: "beginSignIn",
74
73
  completeAction: "finishSignIn",
75
- claimAction: "claimSignIn",
76
74
  signOutAction: "signOut",
77
75
  accountKey: "accountLabel",
78
76
  countKey: "gatewayCount",
@@ -215,27 +213,6 @@ var homeComActions = require_bosch_instances.defineCustomActions({
215
213
  kind: "mutation",
216
214
  auth: "admin"
217
215
  }),
218
- /**
219
- * The form asks while the proxied login page is open: `pending` until the hub captured the
220
- * app-scheme redirect and finished the exchange, then the same fields `finishSignIn` returns.
221
- * Claimed once. A failed exchange answers with its operator-facing message as an error.
222
- */
223
- claimSignIn: require_bosch_instances.customAction(require_bosch_instances.object({ attemptId: require_bosch_instances.string().min(1) }), require_bosch_instances.object({
224
- pending: require_bosch_instances.boolean(),
225
- token: require_bosch_instances.string().optional().meta({ secret: true }),
226
- refresh: require_bosch_instances.string().optional().meta({ secret: true }),
227
- username: require_bosch_instances.string().optional().meta({ secret: true }),
228
- accountLabel: require_bosch_instances.string().optional(),
229
- gatewayCount: require_bosch_instances.number().optional(),
230
- summary: require_bosch_instances.string().optional(),
231
- gatewayId: require_bosch_instances.string().optional(),
232
- brand: HomeComBrandSchema.optional(),
233
- region: HomeComRegionSchema.optional(),
234
- choices: require_bosch_instances.array(gatewayChoice).optional()
235
- }), {
236
- kind: "mutation",
237
- auth: "admin"
238
- }),
239
216
  signOut: require_bosch_instances.customAction(require_bosch_instances.object({}), require_bosch_instances.object({
240
217
  signedOut: require_bosch_instances.literal(true),
241
218
  summary: require_bosch_instances.string()
@@ -302,7 +279,6 @@ function unsupportedDeviceTypeMessage(deviceType) {
302
279
  * names `pointt.gateway.resource.dashapp`, and the Bosch app sends `style_id=tt_bsch`.
303
280
  */
304
281
  var HOMECOM_CLIENT_ID = "762162C0-FA2D-4540-AE66-6489F189FADC";
305
- var HOMECOM_REDIRECT_URI = "com.bosch.tt.dashtt.pointt://app/login";
306
282
  var HOMECOM_AUTHORIZE_URL = "https://singlekey-id.com/auth/connect/authorize";
307
283
  var HOMECOM_TOKEN_URL = "https://singlekey-id.com/auth/connect/token";
308
284
  var HOMECOM_STYLE_ID = "tt_bsch";
@@ -1093,7 +1069,7 @@ function beginHomeComSignIn() {
1093
1069
  const state = b64url((0, node_crypto.randomBytes)(16));
1094
1070
  const url = new URL(HOMECOM_AUTHORIZE_URL);
1095
1071
  url.searchParams.set("client_id", HOMECOM_CLIENT_ID);
1096
- url.searchParams.set("redirect_uri", HOMECOM_REDIRECT_URI);
1072
+ url.searchParams.set("redirect_uri", require_account_integration_offline.HOMECOM_REDIRECT_URI);
1097
1073
  url.searchParams.set("response_type", "code");
1098
1074
  url.searchParams.set("scope", HOMECOM_SCOPE);
1099
1075
  url.searchParams.set("code_challenge", challenge);
@@ -1141,7 +1117,7 @@ async function completeHomeComSignIn(input, fetchFn = globalThis.fetch.bind(glob
1141
1117
  client_id: HOMECOM_CLIENT_ID,
1142
1118
  code,
1143
1119
  code_verifier: input.verifier,
1144
- redirect_uri: HOMECOM_REDIRECT_URI
1120
+ redirect_uri: require_account_integration_offline.HOMECOM_REDIRECT_URI
1145
1121
  }).toString()
1146
1122
  });
1147
1123
  const body = await res.json().catch(() => null);
@@ -1226,42 +1202,6 @@ function finishedFromGateways(tokens, resolved, listFailure) {
1226
1202
  }
1227
1203
  var homeComSignInAttempts = require_account_integration_offline.createSignInAttemptStore();
1228
1204
  //#endregion
1229
- //#region src/homecom/homecom-sign-in-proxy.ts
1230
- /**
1231
- * SingleKey ID serves the HomeCom login page; its scripts and styles come from `cdn.singlekey-id.com`
1232
- * as `type=module` + `crossorigin` files, which the CDN does not CORS-enable for another origin —
1233
- * served from the hub origin through the proxy they load, loaded directly they are refused and the
1234
- * page has no script (only the email field, no way to continue).
1235
- */
1236
- var HOMECOM_LOGIN_HOSTS = ["singlekey-id.com", "cdn.singlekey-id.com"];
1237
- var HOMECOM_APP_SCHEME = HOMECOM_REDIRECT_URI.slice(0, HOMECOM_REDIRECT_URI.indexOf("://") + 3);
1238
- var homeComSignInClaims = require_account_integration_offline.createSignInClaims();
1239
- /** Start an attempt whose `authorizeUrl` is the hub-relative proxied login page. */
1240
- function beginHomeComProxiedSignIn(deps) {
1241
- const nowMs = deps.nowMs ?? (() => Date.now());
1242
- const published = publishHomeComSignIn(homeComSignInAttempts, nowMs());
1243
- if (deps.proxy === null) return published;
1244
- const entry = require_account_integration_offline.openSignInProxy({
1245
- proxy: deps.proxy,
1246
- claims: homeComSignInClaims,
1247
- addonId: deps.addonId,
1248
- attemptId: published.attemptId,
1249
- authorizeUrl: published.authorizeUrl,
1250
- hosts: HOMECOM_LOGIN_HOSTS,
1251
- appScheme: HOMECOM_APP_SCHEME,
1252
- finish: (callback) => finishHomeComSignIn({
1253
- attemptId: published.attemptId,
1254
- callback,
1255
- nowMs: nowMs()
1256
- }, homeComSignInAttempts, deps.fetchFn !== void 0 ? { fetchFn: deps.fetchFn } : {}),
1257
- nowMs
1258
- });
1259
- return {
1260
- attemptId: published.attemptId,
1261
- authorizeUrl: entry
1262
- };
1263
- }
1264
- //#endregion
1265
1205
  //#region src/homecom/homecom-token-persist.ts
1266
1206
  /**
1267
1207
  * Patch the integration's record, one write at a time per integration. Refuses (and says so,
@@ -1965,7 +1905,13 @@ function buildHomeComInstances(records, deps) {
1965
1905
  role: "devices",
1966
1906
  instanceMode: "multiple",
1967
1907
  kind: "account",
1968
- canTest: true
1908
+ canTest: true,
1909
+ kinds: [{
1910
+ id: "connection",
1911
+ label: "Bosch HomeCom",
1912
+ functionCap: "device-provider",
1913
+ role: "devices"
1914
+ }]
1969
1915
  },
1970
1916
  formSchema: () => buildHomeComFormSchema(),
1971
1917
  initialBody: (name) => ({ name }),
@@ -2182,8 +2128,6 @@ var BoschHomeComProviderAddon = class extends require_bosch_instances.BaseDevice
2182
2128
  };
2183
2129
  clients = null;
2184
2130
  instances = null;
2185
- loginProxy = null;
2186
- loginPlane = null;
2187
2131
  constructor() {
2188
2132
  super({});
2189
2133
  }
@@ -2202,7 +2146,6 @@ var BoschHomeComProviderAddon = class extends require_bosch_instances.BaseDevice
2202
2146
  tester: this.buildConnectionTestProvider()
2203
2147
  });
2204
2148
  this.instances = built;
2205
- await this.serveLoginProxy();
2206
2149
  const persistDeps = {
2207
2150
  read: (id) => homeComStoredOf(built.instances, id),
2208
2151
  patch: (id, patch) => built.handle.patch(id, patch),
@@ -2237,19 +2180,9 @@ var BoschHomeComProviderAddon = class extends require_bosch_instances.BaseDevice
2237
2180
  customActions: homeComActions,
2238
2181
  actionHandlers: {
2239
2182
  beginSignIn: async () => ({
2240
- ...beginHomeComProxiedSignIn({
2241
- proxy: this.loginProxy,
2242
- addonId: this.ctx.id
2243
- }),
2244
- summary: "Open the sign-in page and sign in."
2183
+ ...publishHomeComSignIn(homeComSignInAttempts, Date.now()),
2184
+ summary: "Open the sign-in page, sign in, then paste the address the browser stops on."
2245
2185
  }),
2246
- claimSignIn: async (input) => {
2247
- const claim = homeComSignInClaims.claim(input.attemptId, Date.now());
2248
- return claim.state === "pending" ? { pending: true } : {
2249
- pending: false,
2250
- ...claim.result
2251
- };
2252
- },
2253
2186
  finishSignIn: async (input) => finishHomeComSignIn({
2254
2187
  attemptId: input.attemptId,
2255
2188
  callback: input.callback,
@@ -2262,27 +2195,7 @@ var BoschHomeComProviderAddon = class extends require_bosch_instances.BaseDevice
2262
2195
  }
2263
2196
  };
2264
2197
  }
2265
- /** The hub's HTTPS face for the vendor's login pages (D955): admin session only. */
2266
- async serveLoginProxy() {
2267
- const proxy = new require_bosch_instances.VendorLoginProxy({
2268
- addonId: this.ctx.id,
2269
- logger: this.ctx.logger
2270
- });
2271
- try {
2272
- this.loginPlane = await this.ctx.dataPlane?.serve({
2273
- prefix: "vendor-login",
2274
- access: "admin",
2275
- handler: proxy.handler
2276
- }) ?? null;
2277
- if (this.loginPlane !== null) this.loginProxy = proxy;
2278
- } catch (err) {
2279
- this.ctx.logger.warn("HomeCom login proxy failed to serve — sign-in falls back to paste", { meta: { error: require_bosch_instances.errMsg(err) } });
2280
- }
2281
- }
2282
2198
  async onShutdown() {
2283
- await this.loginPlane?.dispose().catch(() => void 0);
2284
- this.loginPlane = null;
2285
- this.loginProxy = null;
2286
2199
  try {
2287
2200
  await this.clients?.shutdown();
2288
2201
  } catch (err) {