@camstack/system 1.2.69 → 1.2.70
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/dist/addon-runner.js +6 -6
- package/dist/addon-runner.mjs +3 -3
- package/dist/addon-utils.js +11 -11
- package/dist/addon-utils.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +3 -3
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +2 -2
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +3 -3
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +2 -2
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +8 -8
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +6 -6
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +3 -3
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/index.d.ts +0 -1
- package/dist/builtins/local-auth/index.js +0 -1
- package/dist/builtins/local-auth/index.mjs +2 -2
- package/dist/builtins/local-auth/local-auth.addon.js +129 -173
- package/dist/builtins/local-auth/local-auth.addon.mjs +130 -173
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +5 -5
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +4 -4
- package/dist/builtins/platform-probe/index.js +4 -4
- package/dist/builtins/platform-probe/index.mjs +3 -3
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +2 -2
- package/dist/builtins/snapshot/index.mjs +2 -2
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +4 -4
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +3 -3
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -2
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-C-QzFJ8v.mjs → dist-CnQXXnK1.mjs} +60 -1
- package/dist/{dist-D7wC-S4p.js → dist-DCLoJf2T.js} +59 -6
- package/dist/{model-download-service-CTBHzORJ.mjs → file-data-plane-CuE_hBli.mjs} +848 -848
- package/dist/index.d.ts +73 -81
- package/dist/index.js +1379 -1346
- package/dist/index.mjs +1362 -1328
- package/dist/kernel/capability-registry.d.ts +26 -0
- package/dist/kernel/config-schema.d.ts +1 -1
- package/dist/{manifest-python-deps-Dz1ryHIN.mjs → manifest-python-deps-DKrHcUZj.mjs} +47 -47
- package/package.json +1 -4
- package/dist/builtins/local-auth/homeassistant-integration.d.ts +0 -7
- package/dist/{model-download-service-Caj1kaSi.js → file-data-plane-DUHPHa-Y.js} +847 -847
- package/dist/{manifest-python-deps-BE6l8Y4W.js → manifest-python-deps-DafB-1hp.js} +47 -47
- package/dist/{resource-monitor-BkP504Vq.mjs → resource-monitor-BWmQ5i-o.mjs} +1 -1
- package/dist/{resource-monitor-DNNomR-i.js → resource-monitor-CdnzxBLP.js} +1 -1
|
@@ -3,46 +3,11 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-DCLoJf2T.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|
|
10
10
|
crypto$1 = require_chunk.__toESM(crypto$1, 1);
|
|
11
|
-
/**
|
|
12
|
-
* Scopes granted to a linked Home Assistant, derived from the tRPC paths the
|
|
13
|
-
* component actually calls. `category:system [create]` was rejected: it would
|
|
14
|
-
* hand `addons.installPackage` to a home-automation bridge.
|
|
15
|
-
*/
|
|
16
|
-
var HOME_ASSISTANT_OAUTH_INTEGRATION = {
|
|
17
|
-
integrationId: "homeassistant",
|
|
18
|
-
displayName: "Home Assistant",
|
|
19
|
-
requestedScopes: [
|
|
20
|
-
{
|
|
21
|
-
type: "category",
|
|
22
|
-
target: "device",
|
|
23
|
-
access: ["view", "create"]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
type: "capability",
|
|
27
|
-
target: "device-manager",
|
|
28
|
-
access: ["view"]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
type: "capability",
|
|
32
|
-
target: "device-state",
|
|
33
|
-
access: ["view"]
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
type: "capability",
|
|
37
|
-
target: "pipeline-orchestrator",
|
|
38
|
-
access: ["view", "create"]
|
|
39
|
-
}
|
|
40
|
-
],
|
|
41
|
-
allowedRedirectPrefixes: ["https://my.home-assistant.io/redirect/oauth"],
|
|
42
|
-
allowedPrivateHostPaths: ["/auth/external/callback"],
|
|
43
|
-
requiresPkce: true
|
|
44
|
-
};
|
|
45
|
-
//#endregion
|
|
46
11
|
//#region src/auth/parse-record.ts
|
|
47
12
|
function parseRecord(kind, schema, data) {
|
|
48
13
|
try {
|
|
@@ -6412,6 +6377,126 @@ var ScopedTokenManager = class {
|
|
|
6412
6377
|
}
|
|
6413
6378
|
return removed;
|
|
6414
6379
|
}
|
|
6380
|
+
};
|
|
6381
|
+
//#endregion
|
|
6382
|
+
//#region src/auth/user-manager.ts
|
|
6383
|
+
var USERS_COLLECTION$1 = "users";
|
|
6384
|
+
function parseUser(data) {
|
|
6385
|
+
return parseRecord("user", require_dist.UserRecordSchema, data);
|
|
6386
|
+
}
|
|
6387
|
+
var UserManager = class {
|
|
6388
|
+
storageAccess;
|
|
6389
|
+
auth;
|
|
6390
|
+
config;
|
|
6391
|
+
constructor(storageAccess, auth, config) {
|
|
6392
|
+
this.storageAccess = storageAccess;
|
|
6393
|
+
this.auth = auth;
|
|
6394
|
+
this.config = config;
|
|
6395
|
+
}
|
|
6396
|
+
get store() {
|
|
6397
|
+
return this.storageAccess.getStore();
|
|
6398
|
+
}
|
|
6399
|
+
async create(input) {
|
|
6400
|
+
if (await this.findByUsername(input.username)) throw new Error(`User with username "${input.username}" already exists`);
|
|
6401
|
+
const passwordHash = await this.auth.hashPassword(input.password);
|
|
6402
|
+
const now = Date.now();
|
|
6403
|
+
const record = {
|
|
6404
|
+
id: node_crypto.randomUUID(),
|
|
6405
|
+
username: input.username,
|
|
6406
|
+
passwordHash,
|
|
6407
|
+
isAdmin: input.isAdmin ?? false,
|
|
6408
|
+
allowedProviders: input.allowedProviders ?? "*",
|
|
6409
|
+
allowedDevices: input.allowedDevices ?? {},
|
|
6410
|
+
scopes: input.scopes ?? [],
|
|
6411
|
+
createdAt: now,
|
|
6412
|
+
updatedAt: now
|
|
6413
|
+
};
|
|
6414
|
+
await this.store.insert.mutate({
|
|
6415
|
+
collection: USERS_COLLECTION$1,
|
|
6416
|
+
record: {
|
|
6417
|
+
id: record.id,
|
|
6418
|
+
data: { ...record }
|
|
6419
|
+
}
|
|
6420
|
+
});
|
|
6421
|
+
return record;
|
|
6422
|
+
}
|
|
6423
|
+
async findByUsername(username) {
|
|
6424
|
+
const results = await this.store.query.query({
|
|
6425
|
+
collection: USERS_COLLECTION$1,
|
|
6426
|
+
filter: { where: { username } }
|
|
6427
|
+
});
|
|
6428
|
+
if (results.length === 0) return null;
|
|
6429
|
+
return parseUser(results[0].data);
|
|
6430
|
+
}
|
|
6431
|
+
async findById(id) {
|
|
6432
|
+
const results = await this.store.query.query({
|
|
6433
|
+
collection: USERS_COLLECTION$1,
|
|
6434
|
+
filter: { where: { id } }
|
|
6435
|
+
});
|
|
6436
|
+
if (results.length === 0) return null;
|
|
6437
|
+
return parseUser(results[0].data);
|
|
6438
|
+
}
|
|
6439
|
+
async validateCredentials(username, password) {
|
|
6440
|
+
const user = await this.findByUsername(username);
|
|
6441
|
+
if (!user) return null;
|
|
6442
|
+
return await this.auth.comparePassword(password, user.passwordHash) ? user : null;
|
|
6443
|
+
}
|
|
6444
|
+
async listAll() {
|
|
6445
|
+
return (await this.store.query.query({ collection: USERS_COLLECTION$1 })).map((r) => {
|
|
6446
|
+
const { passwordHash: _ph, ...rest } = parseUser(r.data);
|
|
6447
|
+
return rest;
|
|
6448
|
+
});
|
|
6449
|
+
}
|
|
6450
|
+
async update(id, data) {
|
|
6451
|
+
const existing = await this.findById(id);
|
|
6452
|
+
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
6453
|
+
await this.store.update.mutate({
|
|
6454
|
+
collection: USERS_COLLECTION$1,
|
|
6455
|
+
id,
|
|
6456
|
+
data: {
|
|
6457
|
+
...existing,
|
|
6458
|
+
...data,
|
|
6459
|
+
updatedAt: Date.now()
|
|
6460
|
+
}
|
|
6461
|
+
});
|
|
6462
|
+
}
|
|
6463
|
+
async delete(id) {
|
|
6464
|
+
await this.store.delete.mutate({
|
|
6465
|
+
collection: USERS_COLLECTION$1,
|
|
6466
|
+
key: id
|
|
6467
|
+
});
|
|
6468
|
+
}
|
|
6469
|
+
async resetPassword(id, newPassword) {
|
|
6470
|
+
const existing = await this.findById(id);
|
|
6471
|
+
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
6472
|
+
const passwordHash = await this.auth.hashPassword(newPassword);
|
|
6473
|
+
await this.store.update.mutate({
|
|
6474
|
+
collection: USERS_COLLECTION$1,
|
|
6475
|
+
id,
|
|
6476
|
+
data: {
|
|
6477
|
+
...existing,
|
|
6478
|
+
passwordHash,
|
|
6479
|
+
updatedAt: Date.now()
|
|
6480
|
+
}
|
|
6481
|
+
});
|
|
6482
|
+
}
|
|
6483
|
+
async ensureAdminExists() {
|
|
6484
|
+
const adminUsername = this.config.get("auth.adminUsername");
|
|
6485
|
+
const adminPassword = this.config.get("auth.adminPassword");
|
|
6486
|
+
if (!adminUsername || !adminPassword) return;
|
|
6487
|
+
const existing = await this.findByUsername(adminUsername);
|
|
6488
|
+
if (existing) {
|
|
6489
|
+
if (!await this.auth.comparePassword(adminPassword, existing.passwordHash)) await this.resetPassword(existing.id, adminPassword);
|
|
6490
|
+
return;
|
|
6491
|
+
}
|
|
6492
|
+
await this.create({
|
|
6493
|
+
username: adminUsername,
|
|
6494
|
+
password: adminPassword,
|
|
6495
|
+
isAdmin: true,
|
|
6496
|
+
allowedProviders: "*",
|
|
6497
|
+
allowedDevices: {}
|
|
6498
|
+
});
|
|
6499
|
+
}
|
|
6415
6500
|
}, i$2 = class extends Error {
|
|
6416
6501
|
constructor(e, t) {
|
|
6417
6502
|
super(e, t), this.name = "OTPError";
|
|
@@ -8718,126 +8803,6 @@ var TotpManager = class {
|
|
|
8718
8803
|
}
|
|
8719
8804
|
};
|
|
8720
8805
|
//#endregion
|
|
8721
|
-
//#region src/auth/user-manager.ts
|
|
8722
|
-
var USERS_COLLECTION$1 = "users";
|
|
8723
|
-
function parseUser(data) {
|
|
8724
|
-
return parseRecord("user", require_dist.UserRecordSchema, data);
|
|
8725
|
-
}
|
|
8726
|
-
var UserManager = class {
|
|
8727
|
-
storageAccess;
|
|
8728
|
-
auth;
|
|
8729
|
-
config;
|
|
8730
|
-
constructor(storageAccess, auth, config) {
|
|
8731
|
-
this.storageAccess = storageAccess;
|
|
8732
|
-
this.auth = auth;
|
|
8733
|
-
this.config = config;
|
|
8734
|
-
}
|
|
8735
|
-
get store() {
|
|
8736
|
-
return this.storageAccess.getStore();
|
|
8737
|
-
}
|
|
8738
|
-
async create(input) {
|
|
8739
|
-
if (await this.findByUsername(input.username)) throw new Error(`User with username "${input.username}" already exists`);
|
|
8740
|
-
const passwordHash = await this.auth.hashPassword(input.password);
|
|
8741
|
-
const now = Date.now();
|
|
8742
|
-
const record = {
|
|
8743
|
-
id: node_crypto.randomUUID(),
|
|
8744
|
-
username: input.username,
|
|
8745
|
-
passwordHash,
|
|
8746
|
-
isAdmin: input.isAdmin ?? false,
|
|
8747
|
-
allowedProviders: input.allowedProviders ?? "*",
|
|
8748
|
-
allowedDevices: input.allowedDevices ?? {},
|
|
8749
|
-
scopes: input.scopes ?? [],
|
|
8750
|
-
createdAt: now,
|
|
8751
|
-
updatedAt: now
|
|
8752
|
-
};
|
|
8753
|
-
await this.store.insert.mutate({
|
|
8754
|
-
collection: USERS_COLLECTION$1,
|
|
8755
|
-
record: {
|
|
8756
|
-
id: record.id,
|
|
8757
|
-
data: { ...record }
|
|
8758
|
-
}
|
|
8759
|
-
});
|
|
8760
|
-
return record;
|
|
8761
|
-
}
|
|
8762
|
-
async findByUsername(username) {
|
|
8763
|
-
const results = await this.store.query.query({
|
|
8764
|
-
collection: USERS_COLLECTION$1,
|
|
8765
|
-
filter: { where: { username } }
|
|
8766
|
-
});
|
|
8767
|
-
if (results.length === 0) return null;
|
|
8768
|
-
return parseUser(results[0].data);
|
|
8769
|
-
}
|
|
8770
|
-
async findById(id) {
|
|
8771
|
-
const results = await this.store.query.query({
|
|
8772
|
-
collection: USERS_COLLECTION$1,
|
|
8773
|
-
filter: { where: { id } }
|
|
8774
|
-
});
|
|
8775
|
-
if (results.length === 0) return null;
|
|
8776
|
-
return parseUser(results[0].data);
|
|
8777
|
-
}
|
|
8778
|
-
async validateCredentials(username, password) {
|
|
8779
|
-
const user = await this.findByUsername(username);
|
|
8780
|
-
if (!user) return null;
|
|
8781
|
-
return await this.auth.comparePassword(password, user.passwordHash) ? user : null;
|
|
8782
|
-
}
|
|
8783
|
-
async listAll() {
|
|
8784
|
-
return (await this.store.query.query({ collection: USERS_COLLECTION$1 })).map((r) => {
|
|
8785
|
-
const { passwordHash: _ph, ...rest } = parseUser(r.data);
|
|
8786
|
-
return rest;
|
|
8787
|
-
});
|
|
8788
|
-
}
|
|
8789
|
-
async update(id, data) {
|
|
8790
|
-
const existing = await this.findById(id);
|
|
8791
|
-
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
8792
|
-
await this.store.update.mutate({
|
|
8793
|
-
collection: USERS_COLLECTION$1,
|
|
8794
|
-
id,
|
|
8795
|
-
data: {
|
|
8796
|
-
...existing,
|
|
8797
|
-
...data,
|
|
8798
|
-
updatedAt: Date.now()
|
|
8799
|
-
}
|
|
8800
|
-
});
|
|
8801
|
-
}
|
|
8802
|
-
async delete(id) {
|
|
8803
|
-
await this.store.delete.mutate({
|
|
8804
|
-
collection: USERS_COLLECTION$1,
|
|
8805
|
-
key: id
|
|
8806
|
-
});
|
|
8807
|
-
}
|
|
8808
|
-
async resetPassword(id, newPassword) {
|
|
8809
|
-
const existing = await this.findById(id);
|
|
8810
|
-
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
8811
|
-
const passwordHash = await this.auth.hashPassword(newPassword);
|
|
8812
|
-
await this.store.update.mutate({
|
|
8813
|
-
collection: USERS_COLLECTION$1,
|
|
8814
|
-
id,
|
|
8815
|
-
data: {
|
|
8816
|
-
...existing,
|
|
8817
|
-
passwordHash,
|
|
8818
|
-
updatedAt: Date.now()
|
|
8819
|
-
}
|
|
8820
|
-
});
|
|
8821
|
-
}
|
|
8822
|
-
async ensureAdminExists() {
|
|
8823
|
-
const adminUsername = this.config.get("auth.adminUsername");
|
|
8824
|
-
const adminPassword = this.config.get("auth.adminPassword");
|
|
8825
|
-
if (!adminUsername || !adminPassword) return;
|
|
8826
|
-
const existing = await this.findByUsername(adminUsername);
|
|
8827
|
-
if (existing) {
|
|
8828
|
-
if (!await this.auth.comparePassword(adminPassword, existing.passwordHash)) await this.resetPassword(existing.id, adminPassword);
|
|
8829
|
-
return;
|
|
8830
|
-
}
|
|
8831
|
-
await this.create({
|
|
8832
|
-
username: adminUsername,
|
|
8833
|
-
password: adminPassword,
|
|
8834
|
-
isAdmin: true,
|
|
8835
|
-
allowedProviders: "*",
|
|
8836
|
-
allowedDevices: {}
|
|
8837
|
-
});
|
|
8838
|
-
}
|
|
8839
|
-
};
|
|
8840
|
-
//#endregion
|
|
8841
8806
|
//#region src/builtins/local-auth/auth-schema.ts
|
|
8842
8807
|
var USERS_COLLECTION = "users";
|
|
8843
8808
|
var API_KEYS_COLLECTION = "api_keys";
|
|
@@ -9658,22 +9623,14 @@ var LocalAuthAddon = class extends require_dist.BaseAddon {
|
|
|
9658
9623
|
return { valid: await this.totpManager.verify(input.userId, input.code) };
|
|
9659
9624
|
}
|
|
9660
9625
|
};
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
capability: require_dist.userManagementCapability,
|
|
9670
|
-
provider: userMgmt
|
|
9671
|
-
},
|
|
9672
|
-
{
|
|
9673
|
-
capability: require_dist.oauthIntegrationCapability,
|
|
9674
|
-
provider: homeAssistantOauth
|
|
9675
|
-
}
|
|
9676
|
-
];
|
|
9626
|
+
this.ctx.logger.info("registered auth-provider + user-management capabilities");
|
|
9627
|
+
return [{
|
|
9628
|
+
capability: require_dist.authProviderCapability,
|
|
9629
|
+
provider: authProvider
|
|
9630
|
+
}, {
|
|
9631
|
+
capability: require_dist.userManagementCapability,
|
|
9632
|
+
provider: userMgmt
|
|
9633
|
+
}];
|
|
9677
9634
|
}
|
|
9678
9635
|
/**
|
|
9679
9636
|
* Drop auth rows that are dead but were never removed: scoped tokens past
|
|
@@ -9712,7 +9669,6 @@ var LocalAuthAddon = class extends require_dist.BaseAddon {
|
|
|
9712
9669
|
//#endregion
|
|
9713
9670
|
exports.ApiKeyManager = ApiKeyManager;
|
|
9714
9671
|
exports.AuthManager = AuthManager;
|
|
9715
|
-
exports.HOME_ASSISTANT_OAUTH_INTEGRATION = HOME_ASSISTANT_OAUTH_INTEGRATION;
|
|
9716
9672
|
exports.LocalAuthAddon = LocalAuthAddon;
|
|
9717
9673
|
exports.default = LocalAuthAddon;
|
|
9718
9674
|
exports.ScopedTokenManager = ScopedTokenManager;
|
|
@@ -1,43 +1,8 @@
|
|
|
1
1
|
import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { ct as userManagementCapability, ft as BaseAddon, g as UserRecordSchema, m as ScopedTokenSchema, r as ApiKeyRecordSchema, x as authProviderCapability } from "../../dist-CnQXXnK1.mjs";
|
|
3
3
|
import * as crypto$2 from "node:crypto";
|
|
4
4
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
5
5
|
import nodeCrypto from "crypto";
|
|
6
|
-
/**
|
|
7
|
-
* Scopes granted to a linked Home Assistant, derived from the tRPC paths the
|
|
8
|
-
* component actually calls. `category:system [create]` was rejected: it would
|
|
9
|
-
* hand `addons.installPackage` to a home-automation bridge.
|
|
10
|
-
*/
|
|
11
|
-
var HOME_ASSISTANT_OAUTH_INTEGRATION = {
|
|
12
|
-
integrationId: "homeassistant",
|
|
13
|
-
displayName: "Home Assistant",
|
|
14
|
-
requestedScopes: [
|
|
15
|
-
{
|
|
16
|
-
type: "category",
|
|
17
|
-
target: "device",
|
|
18
|
-
access: ["view", "create"]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
type: "capability",
|
|
22
|
-
target: "device-manager",
|
|
23
|
-
access: ["view"]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
type: "capability",
|
|
27
|
-
target: "device-state",
|
|
28
|
-
access: ["view"]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
type: "capability",
|
|
32
|
-
target: "pipeline-orchestrator",
|
|
33
|
-
access: ["view", "create"]
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
allowedRedirectPrefixes: ["https://my.home-assistant.io/redirect/oauth"],
|
|
37
|
-
allowedPrivateHostPaths: ["/auth/external/callback"],
|
|
38
|
-
requiresPkce: true
|
|
39
|
-
};
|
|
40
|
-
//#endregion
|
|
41
6
|
//#region src/auth/parse-record.ts
|
|
42
7
|
function parseRecord(kind, schema, data) {
|
|
43
8
|
try {
|
|
@@ -6404,6 +6369,126 @@ var ScopedTokenManager = class {
|
|
|
6404
6369
|
}
|
|
6405
6370
|
return removed;
|
|
6406
6371
|
}
|
|
6372
|
+
};
|
|
6373
|
+
//#endregion
|
|
6374
|
+
//#region src/auth/user-manager.ts
|
|
6375
|
+
var USERS_COLLECTION$1 = "users";
|
|
6376
|
+
function parseUser(data) {
|
|
6377
|
+
return parseRecord("user", UserRecordSchema, data);
|
|
6378
|
+
}
|
|
6379
|
+
var UserManager = class {
|
|
6380
|
+
storageAccess;
|
|
6381
|
+
auth;
|
|
6382
|
+
config;
|
|
6383
|
+
constructor(storageAccess, auth, config) {
|
|
6384
|
+
this.storageAccess = storageAccess;
|
|
6385
|
+
this.auth = auth;
|
|
6386
|
+
this.config = config;
|
|
6387
|
+
}
|
|
6388
|
+
get store() {
|
|
6389
|
+
return this.storageAccess.getStore();
|
|
6390
|
+
}
|
|
6391
|
+
async create(input) {
|
|
6392
|
+
if (await this.findByUsername(input.username)) throw new Error(`User with username "${input.username}" already exists`);
|
|
6393
|
+
const passwordHash = await this.auth.hashPassword(input.password);
|
|
6394
|
+
const now = Date.now();
|
|
6395
|
+
const record = {
|
|
6396
|
+
id: crypto$2.randomUUID(),
|
|
6397
|
+
username: input.username,
|
|
6398
|
+
passwordHash,
|
|
6399
|
+
isAdmin: input.isAdmin ?? false,
|
|
6400
|
+
allowedProviders: input.allowedProviders ?? "*",
|
|
6401
|
+
allowedDevices: input.allowedDevices ?? {},
|
|
6402
|
+
scopes: input.scopes ?? [],
|
|
6403
|
+
createdAt: now,
|
|
6404
|
+
updatedAt: now
|
|
6405
|
+
};
|
|
6406
|
+
await this.store.insert.mutate({
|
|
6407
|
+
collection: USERS_COLLECTION$1,
|
|
6408
|
+
record: {
|
|
6409
|
+
id: record.id,
|
|
6410
|
+
data: { ...record }
|
|
6411
|
+
}
|
|
6412
|
+
});
|
|
6413
|
+
return record;
|
|
6414
|
+
}
|
|
6415
|
+
async findByUsername(username) {
|
|
6416
|
+
const results = await this.store.query.query({
|
|
6417
|
+
collection: USERS_COLLECTION$1,
|
|
6418
|
+
filter: { where: { username } }
|
|
6419
|
+
});
|
|
6420
|
+
if (results.length === 0) return null;
|
|
6421
|
+
return parseUser(results[0].data);
|
|
6422
|
+
}
|
|
6423
|
+
async findById(id) {
|
|
6424
|
+
const results = await this.store.query.query({
|
|
6425
|
+
collection: USERS_COLLECTION$1,
|
|
6426
|
+
filter: { where: { id } }
|
|
6427
|
+
});
|
|
6428
|
+
if (results.length === 0) return null;
|
|
6429
|
+
return parseUser(results[0].data);
|
|
6430
|
+
}
|
|
6431
|
+
async validateCredentials(username, password) {
|
|
6432
|
+
const user = await this.findByUsername(username);
|
|
6433
|
+
if (!user) return null;
|
|
6434
|
+
return await this.auth.comparePassword(password, user.passwordHash) ? user : null;
|
|
6435
|
+
}
|
|
6436
|
+
async listAll() {
|
|
6437
|
+
return (await this.store.query.query({ collection: USERS_COLLECTION$1 })).map((r) => {
|
|
6438
|
+
const { passwordHash: _ph, ...rest } = parseUser(r.data);
|
|
6439
|
+
return rest;
|
|
6440
|
+
});
|
|
6441
|
+
}
|
|
6442
|
+
async update(id, data) {
|
|
6443
|
+
const existing = await this.findById(id);
|
|
6444
|
+
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
6445
|
+
await this.store.update.mutate({
|
|
6446
|
+
collection: USERS_COLLECTION$1,
|
|
6447
|
+
id,
|
|
6448
|
+
data: {
|
|
6449
|
+
...existing,
|
|
6450
|
+
...data,
|
|
6451
|
+
updatedAt: Date.now()
|
|
6452
|
+
}
|
|
6453
|
+
});
|
|
6454
|
+
}
|
|
6455
|
+
async delete(id) {
|
|
6456
|
+
await this.store.delete.mutate({
|
|
6457
|
+
collection: USERS_COLLECTION$1,
|
|
6458
|
+
key: id
|
|
6459
|
+
});
|
|
6460
|
+
}
|
|
6461
|
+
async resetPassword(id, newPassword) {
|
|
6462
|
+
const existing = await this.findById(id);
|
|
6463
|
+
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
6464
|
+
const passwordHash = await this.auth.hashPassword(newPassword);
|
|
6465
|
+
await this.store.update.mutate({
|
|
6466
|
+
collection: USERS_COLLECTION$1,
|
|
6467
|
+
id,
|
|
6468
|
+
data: {
|
|
6469
|
+
...existing,
|
|
6470
|
+
passwordHash,
|
|
6471
|
+
updatedAt: Date.now()
|
|
6472
|
+
}
|
|
6473
|
+
});
|
|
6474
|
+
}
|
|
6475
|
+
async ensureAdminExists() {
|
|
6476
|
+
const adminUsername = this.config.get("auth.adminUsername");
|
|
6477
|
+
const adminPassword = this.config.get("auth.adminPassword");
|
|
6478
|
+
if (!adminUsername || !adminPassword) return;
|
|
6479
|
+
const existing = await this.findByUsername(adminUsername);
|
|
6480
|
+
if (existing) {
|
|
6481
|
+
if (!await this.auth.comparePassword(adminPassword, existing.passwordHash)) await this.resetPassword(existing.id, adminPassword);
|
|
6482
|
+
return;
|
|
6483
|
+
}
|
|
6484
|
+
await this.create({
|
|
6485
|
+
username: adminUsername,
|
|
6486
|
+
password: adminPassword,
|
|
6487
|
+
isAdmin: true,
|
|
6488
|
+
allowedProviders: "*",
|
|
6489
|
+
allowedDevices: {}
|
|
6490
|
+
});
|
|
6491
|
+
}
|
|
6407
6492
|
}, i$2 = class extends Error {
|
|
6408
6493
|
constructor(e, t) {
|
|
6409
6494
|
super(e, t), this.name = "OTPError";
|
|
@@ -8710,126 +8795,6 @@ var TotpManager = class {
|
|
|
8710
8795
|
}
|
|
8711
8796
|
};
|
|
8712
8797
|
//#endregion
|
|
8713
|
-
//#region src/auth/user-manager.ts
|
|
8714
|
-
var USERS_COLLECTION$1 = "users";
|
|
8715
|
-
function parseUser(data) {
|
|
8716
|
-
return parseRecord("user", UserRecordSchema, data);
|
|
8717
|
-
}
|
|
8718
|
-
var UserManager = class {
|
|
8719
|
-
storageAccess;
|
|
8720
|
-
auth;
|
|
8721
|
-
config;
|
|
8722
|
-
constructor(storageAccess, auth, config) {
|
|
8723
|
-
this.storageAccess = storageAccess;
|
|
8724
|
-
this.auth = auth;
|
|
8725
|
-
this.config = config;
|
|
8726
|
-
}
|
|
8727
|
-
get store() {
|
|
8728
|
-
return this.storageAccess.getStore();
|
|
8729
|
-
}
|
|
8730
|
-
async create(input) {
|
|
8731
|
-
if (await this.findByUsername(input.username)) throw new Error(`User with username "${input.username}" already exists`);
|
|
8732
|
-
const passwordHash = await this.auth.hashPassword(input.password);
|
|
8733
|
-
const now = Date.now();
|
|
8734
|
-
const record = {
|
|
8735
|
-
id: crypto$2.randomUUID(),
|
|
8736
|
-
username: input.username,
|
|
8737
|
-
passwordHash,
|
|
8738
|
-
isAdmin: input.isAdmin ?? false,
|
|
8739
|
-
allowedProviders: input.allowedProviders ?? "*",
|
|
8740
|
-
allowedDevices: input.allowedDevices ?? {},
|
|
8741
|
-
scopes: input.scopes ?? [],
|
|
8742
|
-
createdAt: now,
|
|
8743
|
-
updatedAt: now
|
|
8744
|
-
};
|
|
8745
|
-
await this.store.insert.mutate({
|
|
8746
|
-
collection: USERS_COLLECTION$1,
|
|
8747
|
-
record: {
|
|
8748
|
-
id: record.id,
|
|
8749
|
-
data: { ...record }
|
|
8750
|
-
}
|
|
8751
|
-
});
|
|
8752
|
-
return record;
|
|
8753
|
-
}
|
|
8754
|
-
async findByUsername(username) {
|
|
8755
|
-
const results = await this.store.query.query({
|
|
8756
|
-
collection: USERS_COLLECTION$1,
|
|
8757
|
-
filter: { where: { username } }
|
|
8758
|
-
});
|
|
8759
|
-
if (results.length === 0) return null;
|
|
8760
|
-
return parseUser(results[0].data);
|
|
8761
|
-
}
|
|
8762
|
-
async findById(id) {
|
|
8763
|
-
const results = await this.store.query.query({
|
|
8764
|
-
collection: USERS_COLLECTION$1,
|
|
8765
|
-
filter: { where: { id } }
|
|
8766
|
-
});
|
|
8767
|
-
if (results.length === 0) return null;
|
|
8768
|
-
return parseUser(results[0].data);
|
|
8769
|
-
}
|
|
8770
|
-
async validateCredentials(username, password) {
|
|
8771
|
-
const user = await this.findByUsername(username);
|
|
8772
|
-
if (!user) return null;
|
|
8773
|
-
return await this.auth.comparePassword(password, user.passwordHash) ? user : null;
|
|
8774
|
-
}
|
|
8775
|
-
async listAll() {
|
|
8776
|
-
return (await this.store.query.query({ collection: USERS_COLLECTION$1 })).map((r) => {
|
|
8777
|
-
const { passwordHash: _ph, ...rest } = parseUser(r.data);
|
|
8778
|
-
return rest;
|
|
8779
|
-
});
|
|
8780
|
-
}
|
|
8781
|
-
async update(id, data) {
|
|
8782
|
-
const existing = await this.findById(id);
|
|
8783
|
-
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
8784
|
-
await this.store.update.mutate({
|
|
8785
|
-
collection: USERS_COLLECTION$1,
|
|
8786
|
-
id,
|
|
8787
|
-
data: {
|
|
8788
|
-
...existing,
|
|
8789
|
-
...data,
|
|
8790
|
-
updatedAt: Date.now()
|
|
8791
|
-
}
|
|
8792
|
-
});
|
|
8793
|
-
}
|
|
8794
|
-
async delete(id) {
|
|
8795
|
-
await this.store.delete.mutate({
|
|
8796
|
-
collection: USERS_COLLECTION$1,
|
|
8797
|
-
key: id
|
|
8798
|
-
});
|
|
8799
|
-
}
|
|
8800
|
-
async resetPassword(id, newPassword) {
|
|
8801
|
-
const existing = await this.findById(id);
|
|
8802
|
-
if (!existing) throw new Error(`User with id "${id}" not found`);
|
|
8803
|
-
const passwordHash = await this.auth.hashPassword(newPassword);
|
|
8804
|
-
await this.store.update.mutate({
|
|
8805
|
-
collection: USERS_COLLECTION$1,
|
|
8806
|
-
id,
|
|
8807
|
-
data: {
|
|
8808
|
-
...existing,
|
|
8809
|
-
passwordHash,
|
|
8810
|
-
updatedAt: Date.now()
|
|
8811
|
-
}
|
|
8812
|
-
});
|
|
8813
|
-
}
|
|
8814
|
-
async ensureAdminExists() {
|
|
8815
|
-
const adminUsername = this.config.get("auth.adminUsername");
|
|
8816
|
-
const adminPassword = this.config.get("auth.adminPassword");
|
|
8817
|
-
if (!adminUsername || !adminPassword) return;
|
|
8818
|
-
const existing = await this.findByUsername(adminUsername);
|
|
8819
|
-
if (existing) {
|
|
8820
|
-
if (!await this.auth.comparePassword(adminPassword, existing.passwordHash)) await this.resetPassword(existing.id, adminPassword);
|
|
8821
|
-
return;
|
|
8822
|
-
}
|
|
8823
|
-
await this.create({
|
|
8824
|
-
username: adminUsername,
|
|
8825
|
-
password: adminPassword,
|
|
8826
|
-
isAdmin: true,
|
|
8827
|
-
allowedProviders: "*",
|
|
8828
|
-
allowedDevices: {}
|
|
8829
|
-
});
|
|
8830
|
-
}
|
|
8831
|
-
};
|
|
8832
|
-
//#endregion
|
|
8833
8798
|
//#region src/builtins/local-auth/auth-schema.ts
|
|
8834
8799
|
var USERS_COLLECTION = "users";
|
|
8835
8800
|
var API_KEYS_COLLECTION = "api_keys";
|
|
@@ -9650,22 +9615,14 @@ var LocalAuthAddon = class extends BaseAddon {
|
|
|
9650
9615
|
return { valid: await this.totpManager.verify(input.userId, input.code) };
|
|
9651
9616
|
}
|
|
9652
9617
|
};
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
capability: userManagementCapability,
|
|
9662
|
-
provider: userMgmt
|
|
9663
|
-
},
|
|
9664
|
-
{
|
|
9665
|
-
capability: oauthIntegrationCapability,
|
|
9666
|
-
provider: homeAssistantOauth
|
|
9667
|
-
}
|
|
9668
|
-
];
|
|
9618
|
+
this.ctx.logger.info("registered auth-provider + user-management capabilities");
|
|
9619
|
+
return [{
|
|
9620
|
+
capability: authProviderCapability,
|
|
9621
|
+
provider: authProvider
|
|
9622
|
+
}, {
|
|
9623
|
+
capability: userManagementCapability,
|
|
9624
|
+
provider: userMgmt
|
|
9625
|
+
}];
|
|
9669
9626
|
}
|
|
9670
9627
|
/**
|
|
9671
9628
|
* Drop auth rows that are dead but were never removed: scoped tokens past
|
|
@@ -9702,4 +9659,4 @@ var LocalAuthAddon = class extends BaseAddon {
|
|
|
9702
9659
|
}
|
|
9703
9660
|
};
|
|
9704
9661
|
//#endregion
|
|
9705
|
-
export { LocalAuthAddon, LocalAuthAddon as default, require_safe_buffer as a, require_ms as i, ScopedTokenManager as n, ApiKeyManager as o, AuthManager as r,
|
|
9662
|
+
export { LocalAuthAddon, LocalAuthAddon as default, require_safe_buffer as a, require_ms as i, ScopedTokenManager as n, ApiKeyManager as o, AuthManager as r, UserManager as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-DCLoJf2T.js");
|
|
4
4
|
let node_os = require("node:os");
|
|
5
5
|
node_os = require_chunk.__toESM(node_os);
|
|
6
6
|
//#region src/builtins/local-network/local-network.addon.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as localNetworkCapability,
|
|
1
|
+
import { K as localNetworkCapability, Rt as EventCategory, ft as BaseAddon } from "../../dist-CnQXXnK1.mjs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
//#region src/builtins/local-network/local-network.addon.ts
|
|
4
4
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-DCLoJf2T.js");
|
|
7
7
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
8
8
|
/**
|
|
9
9
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ft as BaseAddon, q as logDestinationCapability } from "../../dist-CnQXXnK1.mjs";
|
|
2
2
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
3
3
|
/**
|
|
4
4
|
* Loki rejects a label name that is not a valid Prometheus label
|