@camstack/system 1.2.147 → 1.2.148
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 +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/auth/auth-manager.d.ts +17 -1
- package/dist/auth/token-expiry.d.ts +39 -0
- package/dist/auth/user-manager.d.ts +2 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- 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 +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- 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 +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- 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/auth-config-reader.d.ts +20 -0
- package/dist/builtins/local-auth/local-auth.addon.js +211 -17
- package/dist/builtins/local-auth/local-auth.addon.mjs +211 -17
- 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 +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- 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 +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +12 -11
- package/dist/builtins/system-config/system-config.addon.mjs +12 -11
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-Dl6MFXPr.js → dist-B-mBrEz9.js} +1 -1
- package/dist/{dist-DrBc-7Y3.mjs → dist-BwD83D2f.mjs} +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{manifest-python-deps-FYZBHc3v.js → manifest-python-deps-BV_Cy99l.js} +1 -1
- package/dist/{manifest-python-deps-DhT0oFOZ.mjs → manifest-python-deps-DpRX9LtD.mjs} +1 -1
- package/dist/{retired-settings-keys-CF5r4YKq.mjs → retired-settings-keys-CRKpAmSn.mjs} +1 -1
- package/dist/{retired-settings-keys-6w_JOqBg.js → retired-settings-keys-Davtjo5p.js} +1 -1
- package/package.json +6 -4
package/dist/addon-runner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
2
|
+
const require_manifest_python_deps = require("./manifest-python-deps-BV_Cy99l.js");
|
|
3
3
|
const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_chunk.__toESM(node_path);
|
package/dist/addon-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as createUdsLoggerWithControl, Ht as startRunnerHeapWatch, I as LocalChildClient, Nt as RUNNER_RSS_BUDGET_ENV, bt as resolveAddonClass, i as createUdsAddonContext, it as setWorkerNativeCapsChangeListener, nt as getWorkerNativeCapSnapshot, ot as validateProviderRegistrations, t as installManifestPythonDeps, tt as getWorkerNativeCapProvider, yt as installManifestNativeDeps } from "./manifest-python-deps-
|
|
1
|
+
import { F as createUdsLoggerWithControl, Ht as startRunnerHeapWatch, I as LocalChildClient, Nt as RUNNER_RSS_BUDGET_ENV, bt as resolveAddonClass, i as createUdsAddonContext, it as setWorkerNativeCapsChangeListener, nt as getWorkerNativeCapSnapshot, ot as validateProviderRegistrations, t as installManifestPythonDeps, tt as getWorkerNativeCapProvider, yt as installManifestNativeDeps } from "./manifest-python-deps-DpRX9LtD.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-F__gp_VX.mjs";
|
|
3
3
|
import { register } from "node:module";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -2,13 +2,29 @@ import { IScopedLogger, TokenPayload, SsoBridgeClaimsSchema } from '@camstack/ty
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
export type { TokenPayload };
|
|
4
4
|
export type AuthConfigReader = {
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* `undefined` is part of the contract, not an accident: a reader answers
|
|
7
|
+
* only the paths it can (`local-auth` pre-resolves a fixed set; a
|
|
8
|
+
* `ConfigManager` falls through to RUNTIME_DEFAULTS and then to nothing).
|
|
9
|
+
* Every consumer here must handle the absent case explicitly.
|
|
10
|
+
*/
|
|
11
|
+
get<T>(path: string): T | undefined;
|
|
6
12
|
update(section: string, data: Record<string, unknown>): void;
|
|
7
13
|
};
|
|
8
14
|
export declare class AuthManager {
|
|
9
15
|
private readonly config;
|
|
10
16
|
private readonly jwtSecret;
|
|
11
17
|
private readonly logger;
|
|
18
|
+
/**
|
|
19
|
+
* Offending `auth.tokenExpiry` values already reported by this instance.
|
|
20
|
+
*
|
|
21
|
+
* `signToken` re-reads the setting on EVERY mint so an operator's change
|
|
22
|
+
* takes effect without a restart — which also means a bad value would log
|
|
23
|
+
* once per login and once per silent refresh from every viewer. The refusal
|
|
24
|
+
* must be visible, not repeated: the first mint after a bad save logs, the
|
|
25
|
+
* rest resolve silently to the same default until the value changes.
|
|
26
|
+
*/
|
|
27
|
+
private readonly reportedInvalidExpiries;
|
|
12
28
|
constructor(config: AuthConfigReader, logger?: IScopedLogger);
|
|
13
29
|
signToken(payload: Omit<TokenPayload, 'iat' | 'exp'>): string;
|
|
14
30
|
verifyToken(token: string): TokenPayload;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { DEFAULT_TOKEN_EXPIRY, IScopedLogger } from '@camstack/types';
|
|
2
|
+
/** Why a candidate value was refused. Feeds the log line, not the UI. */
|
|
3
|
+
export type TokenExpiryRejection = 'not-a-string' | 'malformed' | 'too-short' | 'too-long';
|
|
4
|
+
interface TokenExpiryOutcome {
|
|
5
|
+
/**
|
|
6
|
+
* Lifetime to hand `jwt.sign`, in SECONDS.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately a number rather than the duration string: `expiresIn` accepts
|
|
9
|
+
* both, but the string branch re-parses through `ms` — which is the branch
|
|
10
|
+
* that reads a bare number as milliseconds. Resolving to seconds here means
|
|
11
|
+
* exactly one parser decides what the operator's text meant, and it is this
|
|
12
|
+
* one.
|
|
13
|
+
*/
|
|
14
|
+
readonly seconds: number;
|
|
15
|
+
/** The duration string actually applied — for the log line and the UI story. */
|
|
16
|
+
readonly value: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TokenExpiryRejected extends TokenExpiryOutcome {
|
|
19
|
+
readonly ok: false;
|
|
20
|
+
readonly reason: TokenExpiryRejection;
|
|
21
|
+
}
|
|
22
|
+
export interface TokenExpiryAccepted extends TokenExpiryOutcome {
|
|
23
|
+
readonly ok: true;
|
|
24
|
+
readonly reason?: undefined;
|
|
25
|
+
}
|
|
26
|
+
export type TokenExpiryResult = TokenExpiryAccepted | TokenExpiryRejected;
|
|
27
|
+
/**
|
|
28
|
+
* Parse a configured `auth.tokenExpiry`. An absent/blank value is not a
|
|
29
|
+
* rejection — it is "operator never set it" and resolves to the default
|
|
30
|
+
* without a log line.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseTokenExpiry(configured: unknown): TokenExpiryResult;
|
|
33
|
+
/**
|
|
34
|
+
* Report a refused `auth.tokenExpiry`. Separate from {@link parseTokenExpiry}
|
|
35
|
+
* so the caller owns HOW OFTEN it speaks — the signer re-reads the setting on
|
|
36
|
+
* every mint and must not turn one bad save into a line per login.
|
|
37
|
+
*/
|
|
38
|
+
export declare function logTokenExpiryRejection(configured: unknown, rejection: TokenExpiryRejected, logger: IScopedLogger): void;
|
|
39
|
+
export { DEFAULT_TOKEN_EXPIRY };
|
|
@@ -14,7 +14,8 @@ export interface UserStorageAccess {
|
|
|
14
14
|
getStore(): SettingsStoreClient;
|
|
15
15
|
}
|
|
16
16
|
export interface UserConfigReader {
|
|
17
|
-
get
|
|
17
|
+
/** See `AuthConfigReader.get` — a reader answers only the paths it resolved. */
|
|
18
|
+
get<T>(path: string): T | undefined;
|
|
18
19
|
}
|
|
19
20
|
export declare class UserManager {
|
|
20
21
|
private readonly storageAccess;
|
|
@@ -3,7 +3,7 @@ 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-B-mBrEz9.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ot as errMsg, S as addonPagesCapability, kt as BaseAddon, tn as EventCategory } from "../../dist-
|
|
1
|
+
import { Ot as errMsg, S as addonPagesCapability, kt as BaseAddon, tn as EventCategory } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ 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-B-mBrEz9.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ot as errMsg, kt as BaseAddon, tn as EventCategory, w as addonWidgetsCapability } from "../../dist-
|
|
1
|
+
import { Ot as errMsg, kt as BaseAddon, tn as EventCategory, w as addonWidgetsCapability } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -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-B-mBrEz9.js");
|
|
7
7
|
//#region src/builtins/alerts/prune-policy.ts
|
|
8
8
|
/**
|
|
9
9
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ht as createEvent, Ot as errMsg, T as alertsCapability, kt as BaseAddon, n as AlertSchema, tn as EventCategory } from "../../dist-
|
|
1
|
+
import { Ht as createEvent, Ot as errMsg, T as alertsCapability, kt as BaseAddon, n as AlertSchema, tn as EventCategory } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
//#region src/builtins/alerts/prune-policy.ts
|
|
3
3
|
/**
|
|
4
4
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -3,7 +3,7 @@ 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-B-mBrEz9.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let buffer = require("buffer");
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as backupCapability, kt as BaseAddon, tn as EventCategory } from "../../dist-
|
|
1
|
+
import { D as backupCapability, kt as BaseAddon, tn as EventCategory } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -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-B-mBrEz9.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { kt as BaseAddon, rt as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { kt as BaseAddon, rt as logDestinationCapability } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -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-B-mBrEz9.js");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as coreBlockIdFromAddonId, N as coreBlocksCapability, Ot as errMsg, c as CoreBlockSchema, j as coreBlockAddonId, kt as BaseAddon, o as CORE_BLOCKS_ADDON_ID, s as CORE_BLOCK_ADDON_PREFIX, u as DeclaredDevices } from "../../dist-
|
|
1
|
+
import { M as coreBlockIdFromAddonId, N as coreBlocksCapability, Ot as errMsg, c as CoreBlockSchema, j as coreBlockAddonId, kt as BaseAddon, o as CORE_BLOCKS_ADDON_ID, s as CORE_BLOCK_ADDON_PREFIX, u as DeclaredDevices } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_retired_settings_keys = require("../../retired-settings-keys-
|
|
6
|
+
const require_dist = require("../../dist-B-mBrEz9.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-Davtjo5p.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let _camstack_types_node = require("@camstack/types/node");
|
|
10
10
|
//#region src/builtins/device-manager/adoption-job-engine.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as buildStreamParamsConfigSchema, Ft as DeviceType, H as enumerateItemArrayFields, L as deviceManagerCapability, Nt as DeviceFeature, Ot as errMsg, Pt as DeviceRole, R as deviceStateCapability, Rt as WELL_KNOWN_TAB_MAP, U as enumerateSchemaFields, _ as STREAM_PROFILE_META, a as CAP_NAMES_WITH_STATUS, d as DeviceStatusSchema, en as sleep, ht as runtimeStatePolicyFor, kt as BaseAddon, lt as parseStreamParamsFormPatch, qt as isDeviceConfigCap, st as normalizeUnit, t as ALL_CAPABILITY_DEFINITIONS, tn as EventCategory, z as deviceStatusCapability } from "../../dist-
|
|
2
|
-
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-
|
|
1
|
+
import { A as buildStreamParamsConfigSchema, Ft as DeviceType, H as enumerateItemArrayFields, L as deviceManagerCapability, Nt as DeviceFeature, Ot as errMsg, Pt as DeviceRole, R as deviceStateCapability, Rt as WELL_KNOWN_TAB_MAP, U as enumerateSchemaFields, _ as STREAM_PROFILE_META, a as CAP_NAMES_WITH_STATUS, d as DeviceStatusSchema, en as sleep, ht as runtimeStatePolicyFor, kt as BaseAddon, lt as parseStreamParamsFormPatch, qt as isDeviceConfigCap, st as normalizeUnit, t as ALL_CAPABILITY_DEFINITIONS, tn as EventCategory, z as deviceStatusCapability } from "../../dist-BwD83D2f.mjs";
|
|
2
|
+
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-CRKpAmSn.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
5
5
|
//#region src/builtins/device-manager/adoption-job-engine.ts
|
|
@@ -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-B-mBrEz9.js");
|
|
7
7
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
8
8
|
/**
|
|
9
9
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as doorbellCapability, Ft as DeviceType, Ht as createEvent, O as bareAddonId, Ot as errMsg, Q as isSourceCap, W as evaluateSensorEdge, Z as isSameAddonId, g as SOURCE_DEVICE_TYPES, h as SOURCE_CAPS, kt as BaseAddon, tn as EventCategory } from "../../dist-
|
|
1
|
+
import { B as doorbellCapability, Ft as DeviceType, Ht as createEvent, O as bareAddonId, Ot as errMsg, Q as isSourceCap, W as evaluateSensorEdge, Z as isSameAddonId, g as SOURCE_DEVICE_TYPES, h as SOURCE_CAPS, kt as BaseAddon, tn as EventCategory } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
3
3
|
/**
|
|
4
4
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -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-B-mBrEz9.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { kt as BaseAddon, rt as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { kt as BaseAddon, rt as logDestinationCapability } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-B-mBrEz9.js");
|
|
4
4
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
5
5
|
var NO_DEVICES = "liveness:no-devices";
|
|
6
6
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ht as createEvent, Ot as errMsg, kt as BaseAddon, tn as EventCategory } from "../../dist-
|
|
1
|
+
import { Ht as createEvent, Ot as errMsg, kt as BaseAddon, tn as EventCategory } from "../../dist-BwD83D2f.mjs";
|
|
2
2
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
3
3
|
var NO_DEVICES = "liveness:no-devices";
|
|
4
4
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AuthConfigReader } from '../../auth/auth-manager.js';
|
|
2
|
+
/** The values `local-auth` pre-resolves before constructing its AuthManager. */
|
|
3
|
+
export interface ResolvedAuthConfig {
|
|
4
|
+
readonly jwtSecret: string;
|
|
5
|
+
readonly adminUsername: string;
|
|
6
|
+
readonly adminPassword: string;
|
|
7
|
+
/**
|
|
8
|
+
* Operator-configured session lifetime. `undefined` when the `auth` section
|
|
9
|
+
* carries no value — the signer then applies `DEFAULT_TOKEN_EXPIRY`, which
|
|
10
|
+
* is where the default belongs (one default, one place).
|
|
11
|
+
*/
|
|
12
|
+
readonly tokenExpiry: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
/** Persist the generated JWT secret. Called by AuthManager on first boot. */
|
|
15
|
+
export type AuthSectionWriter = (patch: Record<string, unknown>) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Every config path this reader can answer. Anything else resolves to
|
|
18
|
+
* `undefined` by construction — see the module docblock.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createAuthConfigReader(resolved: ResolvedAuthConfig, writeAuthSection: AuthSectionWriter): AuthConfigReader;
|
|
@@ -3,7 +3,7 @@ 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-B-mBrEz9.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");
|
|
@@ -6017,8 +6017,158 @@ var require_jsonwebtoken = /* @__PURE__ */ require_chunk.__commonJSMin(((exports
|
|
|
6017
6017
|
};
|
|
6018
6018
|
}));
|
|
6019
6019
|
//#endregion
|
|
6020
|
-
//#region src/auth/
|
|
6020
|
+
//#region src/auth/token-expiry.ts
|
|
6021
6021
|
var import_jsonwebtoken = /* @__PURE__ */ require_chunk.__toESM(require_jsonwebtoken());
|
|
6022
|
+
/**
|
|
6023
|
+
* Validation for the operator-configured session-JWT lifetime
|
|
6024
|
+
* (`auth.tokenExpiry`, System → Settings → Authentication → Token Expiry).
|
|
6025
|
+
*
|
|
6026
|
+
* WHY THIS EXISTS. The field is a free-text box that reaches `jwt.sign`'s
|
|
6027
|
+
* `expiresIn`. Two things go wrong without a gate in front of it:
|
|
6028
|
+
*
|
|
6029
|
+
* 1. `jsonwebtoken` THROWS on a value it cannot parse. The only caller is
|
|
6030
|
+
* the login/refresh path, so one typo in a settings form turns every
|
|
6031
|
+
* login into a 500 — a self-inflicted outage from a text field.
|
|
6032
|
+
* 2. `jsonwebtoken` hands a bare numeric STRING to `ms()`, which reads it
|
|
6033
|
+
* as MILLISECONDS. An operator who types `3600` meaning "an hour" gets
|
|
6034
|
+
* a token that dies in 3.6 seconds. A bare number is therefore rejected
|
|
6035
|
+
* rather than interpreted — the field's own description, placeholder and
|
|
6036
|
+
* default are all duration strings (`24h`, `7d`, `30d`).
|
|
6037
|
+
*
|
|
6038
|
+
* A rejection never becomes an unbounded lifetime — it resolves to
|
|
6039
|
+
* {@link DEFAULT_TOKEN_EXPIRY}, the single documented default — and it is
|
|
6040
|
+
* never silent: `parseTokenExpiry` reports the refusal in its result and
|
|
6041
|
+
* `logTokenExpiryRejection` renders it. The two are separate so the caller
|
|
6042
|
+
* owns how often it speaks; the signer re-reads on every mint.
|
|
6043
|
+
*/
|
|
6044
|
+
/**
|
|
6045
|
+
* The `ms`-compatible duration grammar `jsonwebtoken` accepts, MINUS the bare
|
|
6046
|
+
* number (see the docblock above). A unit is mandatory.
|
|
6047
|
+
*/
|
|
6048
|
+
var DURATION_PATTERN = /^(\d+(?:\.\d+)?)\s*(ms|milliseconds?|msecs?|s|secs?|seconds?|m|mins?|minutes?|h|hrs?|hours?|d|days?|w|weeks?|y|yrs?|years?)$/i;
|
|
6049
|
+
/** Multiplier from each accepted unit to milliseconds. */
|
|
6050
|
+
var UNIT_MS = {
|
|
6051
|
+
ms: 1,
|
|
6052
|
+
msec: 1,
|
|
6053
|
+
msecs: 1,
|
|
6054
|
+
millisecond: 1,
|
|
6055
|
+
milliseconds: 1,
|
|
6056
|
+
s: 1e3,
|
|
6057
|
+
sec: 1e3,
|
|
6058
|
+
secs: 1e3,
|
|
6059
|
+
second: 1e3,
|
|
6060
|
+
seconds: 1e3,
|
|
6061
|
+
m: 6e4,
|
|
6062
|
+
min: 6e4,
|
|
6063
|
+
mins: 6e4,
|
|
6064
|
+
minute: 6e4,
|
|
6065
|
+
minutes: 6e4,
|
|
6066
|
+
h: 36e5,
|
|
6067
|
+
hr: 36e5,
|
|
6068
|
+
hrs: 36e5,
|
|
6069
|
+
hour: 36e5,
|
|
6070
|
+
hours: 36e5,
|
|
6071
|
+
d: 864e5,
|
|
6072
|
+
day: 864e5,
|
|
6073
|
+
days: 864e5,
|
|
6074
|
+
w: 6048e5,
|
|
6075
|
+
week: 6048e5,
|
|
6076
|
+
weeks: 6048e5,
|
|
6077
|
+
y: 315576e5,
|
|
6078
|
+
yr: 315576e5,
|
|
6079
|
+
yrs: 315576e5,
|
|
6080
|
+
year: 315576e5,
|
|
6081
|
+
years: 315576e5
|
|
6082
|
+
};
|
|
6083
|
+
/**
|
|
6084
|
+
* Shortest accepted lifetime. Below a minute the token expires inside the
|
|
6085
|
+
* round trip that issued it and the operator sees "logged out immediately",
|
|
6086
|
+
* which reads as a broken server rather than as a bad setting.
|
|
6087
|
+
*/
|
|
6088
|
+
var MIN_EXPIRY_MS = 6e4;
|
|
6089
|
+
/**
|
|
6090
|
+
* Longest accepted lifetime. A year is already far past "a device left
|
|
6091
|
+
* unopened for weeks"; anything longer is an infinite-lifetime token wearing
|
|
6092
|
+
* a duration string.
|
|
6093
|
+
*/
|
|
6094
|
+
var MAX_EXPIRY_MS = 365 * 864e5;
|
|
6095
|
+
/** Milliseconds for a duration string, or `null` when it is not one. */
|
|
6096
|
+
function durationMs(candidate) {
|
|
6097
|
+
const match = DURATION_PATTERN.exec(candidate);
|
|
6098
|
+
if (match === null) return null;
|
|
6099
|
+
const amount = Number(match[1]);
|
|
6100
|
+
const unitMs = UNIT_MS[match[2].toLowerCase()];
|
|
6101
|
+
if (!Number.isFinite(amount) || unitMs === void 0) return null;
|
|
6102
|
+
return amount * unitMs;
|
|
6103
|
+
}
|
|
6104
|
+
/**
|
|
6105
|
+
* The default, pre-parsed. Computed from {@link DEFAULT_TOKEN_EXPIRY} rather
|
|
6106
|
+
* than written out again — a second spelling of the same default is the defect
|
|
6107
|
+
* this module exists to close.
|
|
6108
|
+
*/
|
|
6109
|
+
var DEFAULT_SECONDS = (() => {
|
|
6110
|
+
const ms = durationMs("30d");
|
|
6111
|
+
/* c8 ignore next -- unreachable unless DEFAULT_TOKEN_EXPIRY stops being a duration */
|
|
6112
|
+
if (ms === null) throw new Error(`DEFAULT_TOKEN_EXPIRY is not a duration: 30d`);
|
|
6113
|
+
return ms / 1e3;
|
|
6114
|
+
})();
|
|
6115
|
+
function refuse(reason) {
|
|
6116
|
+
return {
|
|
6117
|
+
ok: false,
|
|
6118
|
+
reason,
|
|
6119
|
+
seconds: DEFAULT_SECONDS,
|
|
6120
|
+
value: "30d"
|
|
6121
|
+
};
|
|
6122
|
+
}
|
|
6123
|
+
/**
|
|
6124
|
+
* Parse a configured `auth.tokenExpiry`. An absent/blank value is not a
|
|
6125
|
+
* rejection — it is "operator never set it" and resolves to the default
|
|
6126
|
+
* without a log line.
|
|
6127
|
+
*/
|
|
6128
|
+
function parseTokenExpiry(configured) {
|
|
6129
|
+
if (configured === void 0 || configured === null) return {
|
|
6130
|
+
ok: true,
|
|
6131
|
+
seconds: DEFAULT_SECONDS,
|
|
6132
|
+
value: "30d"
|
|
6133
|
+
};
|
|
6134
|
+
if (typeof configured !== "string") return refuse("not-a-string");
|
|
6135
|
+
const trimmed = configured.trim();
|
|
6136
|
+
if (trimmed === "") return {
|
|
6137
|
+
ok: true,
|
|
6138
|
+
seconds: DEFAULT_SECONDS,
|
|
6139
|
+
value: "30d"
|
|
6140
|
+
};
|
|
6141
|
+
const totalMs = durationMs(trimmed);
|
|
6142
|
+
if (totalMs === null) return refuse("malformed");
|
|
6143
|
+
if (totalMs < MIN_EXPIRY_MS) return refuse("too-short");
|
|
6144
|
+
if (totalMs > MAX_EXPIRY_MS) return refuse("too-long");
|
|
6145
|
+
return {
|
|
6146
|
+
ok: true,
|
|
6147
|
+
seconds: totalMs / 1e3,
|
|
6148
|
+
value: trimmed
|
|
6149
|
+
};
|
|
6150
|
+
}
|
|
6151
|
+
/** Human-readable tail for the rejection log line. */
|
|
6152
|
+
var REJECTION_DETAIL = {
|
|
6153
|
+
"not-a-string": "value is not a string",
|
|
6154
|
+
malformed: "not a duration string (expected e.g. 24h, 7d, 30d — a bare number is NOT seconds)",
|
|
6155
|
+
"too-short": `shorter than the ${MIN_EXPIRY_MS / 1e3}s minimum`,
|
|
6156
|
+
"too-long": `longer than the ${MAX_EXPIRY_MS / 864e5}d maximum`
|
|
6157
|
+
};
|
|
6158
|
+
/**
|
|
6159
|
+
* Report a refused `auth.tokenExpiry`. Separate from {@link parseTokenExpiry}
|
|
6160
|
+
* so the caller owns HOW OFTEN it speaks — the signer re-reads the setting on
|
|
6161
|
+
* every mint and must not turn one bad save into a line per login.
|
|
6162
|
+
*/
|
|
6163
|
+
function logTokenExpiryRejection(configured, rejection, logger) {
|
|
6164
|
+
logger.warn(`auth.tokenExpiry REJECTED — ${REJECTION_DETAIL[rejection.reason]}; signing with the default 30d instead`, { meta: {
|
|
6165
|
+
configured,
|
|
6166
|
+
reason: rejection.reason,
|
|
6167
|
+
applied: rejection.value
|
|
6168
|
+
} });
|
|
6169
|
+
}
|
|
6170
|
+
//#endregion
|
|
6171
|
+
//#region src/auth/auth-manager.ts
|
|
6022
6172
|
/** Minimal no-op logger for default parameter */
|
|
6023
6173
|
var noopLogger = {
|
|
6024
6174
|
debug() {},
|
|
@@ -6036,6 +6186,16 @@ var AuthManager = class {
|
|
|
6036
6186
|
config;
|
|
6037
6187
|
jwtSecret;
|
|
6038
6188
|
logger;
|
|
6189
|
+
/**
|
|
6190
|
+
* Offending `auth.tokenExpiry` values already reported by this instance.
|
|
6191
|
+
*
|
|
6192
|
+
* `signToken` re-reads the setting on EVERY mint so an operator's change
|
|
6193
|
+
* takes effect without a restart — which also means a bad value would log
|
|
6194
|
+
* once per login and once per silent refresh from every viewer. The refusal
|
|
6195
|
+
* must be visible, not repeated: the first mint after a bad save logs, the
|
|
6196
|
+
* rest resolve silently to the same default until the value changes.
|
|
6197
|
+
*/
|
|
6198
|
+
reportedInvalidExpiries = /* @__PURE__ */ new Set();
|
|
6039
6199
|
constructor(config, logger = noopLogger) {
|
|
6040
6200
|
this.config = config;
|
|
6041
6201
|
this.logger = logger;
|
|
@@ -6050,8 +6210,15 @@ var AuthManager = class {
|
|
|
6050
6210
|
}
|
|
6051
6211
|
signToken(payload) {
|
|
6052
6212
|
const configured = this.config.get("auth.tokenExpiry");
|
|
6053
|
-
const
|
|
6054
|
-
|
|
6213
|
+
const parsed = parseTokenExpiry(configured);
|
|
6214
|
+
if (!parsed.ok) {
|
|
6215
|
+
const seen = typeof configured === "string" ? configured : JSON.stringify(configured);
|
|
6216
|
+
if (!this.reportedInvalidExpiries.has(seen)) {
|
|
6217
|
+
this.reportedInvalidExpiries.add(seen);
|
|
6218
|
+
logTokenExpiryRejection(configured, parsed, this.logger);
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
return import_jsonwebtoken.sign({ ...payload }, this.jwtSecret, { expiresIn: parsed.seconds });
|
|
6055
6222
|
}
|
|
6056
6223
|
verifyToken(token) {
|
|
6057
6224
|
return import_jsonwebtoken.verify(token, this.jwtSecret);
|
|
@@ -8822,6 +8989,38 @@ var TotpManager = class {
|
|
|
8822
8989
|
}
|
|
8823
8990
|
};
|
|
8824
8991
|
//#endregion
|
|
8992
|
+
//#region src/builtins/local-auth/auth-config-reader.ts
|
|
8993
|
+
/**
|
|
8994
|
+
* Every config path this reader can answer. Anything else resolves to
|
|
8995
|
+
* `undefined` by construction — see the module docblock.
|
|
8996
|
+
*/
|
|
8997
|
+
function createAuthConfigReader(resolved, writeAuthSection) {
|
|
8998
|
+
return {
|
|
8999
|
+
get(path) {
|
|
9000
|
+
switch (path) {
|
|
9001
|
+
case "auth.jwtSecret": return narrow(resolved.jwtSecret);
|
|
9002
|
+
case "auth.adminUsername": return narrow(resolved.adminUsername);
|
|
9003
|
+
case "auth.adminPassword": return narrow(resolved.adminPassword);
|
|
9004
|
+
case "auth.tokenExpiry": return narrow(resolved.tokenExpiry);
|
|
9005
|
+
default: return;
|
|
9006
|
+
}
|
|
9007
|
+
},
|
|
9008
|
+
update(_section, data) {
|
|
9009
|
+
if (typeof data["jwtSecret"] === "string") writeAuthSection({ jwtSecret: data["jwtSecret"] });
|
|
9010
|
+
}
|
|
9011
|
+
};
|
|
9012
|
+
}
|
|
9013
|
+
/**
|
|
9014
|
+
* The one documented type boundary in this module. `AuthConfigReader.get` is
|
|
9015
|
+
* the legacy `get<T>(path)` shape shared with `ConfigManager.get`, which is
|
|
9016
|
+
* likewise unchecked at runtime — every value returned here is a `string |
|
|
9017
|
+
* undefined` the caller immediately re-validates (`parseTokenExpiry`, the
|
|
9018
|
+
* truthiness gate on `jwtSecret`).
|
|
9019
|
+
*/
|
|
9020
|
+
function narrow(value) {
|
|
9021
|
+
return value;
|
|
9022
|
+
}
|
|
9023
|
+
//#endregion
|
|
8825
9024
|
//#region src/builtins/local-auth/auth-schema.ts
|
|
8826
9025
|
/**
|
|
8827
9026
|
* @durable class=config owner=local-auth
|
|
@@ -9470,19 +9669,14 @@ var LocalAuthAddon = class extends require_dist.BaseAddon {
|
|
|
9470
9669
|
}
|
|
9471
9670
|
async onInitialize() {
|
|
9472
9671
|
const authSection = await this.ctx.settings?.getSection("auth") ?? {};
|
|
9473
|
-
const
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
},
|
|
9482
|
-
update: (_section, data) => {
|
|
9483
|
-
if (typeof data["jwtSecret"] === "string") this.ctx.settings?.setSection("auth", { jwtSecret: data["jwtSecret"] });
|
|
9484
|
-
}
|
|
9485
|
-
};
|
|
9672
|
+
const reader = createAuthConfigReader({
|
|
9673
|
+
jwtSecret: typeof authSection["jwtSecret"] === "string" ? authSection["jwtSecret"] : this.config.jwtSecret ?? "",
|
|
9674
|
+
adminUsername: typeof authSection["adminUsername"] === "string" && authSection["adminUsername"] ? authSection["adminUsername"] : this.config.adminUsername ?? "",
|
|
9675
|
+
adminPassword: typeof authSection["adminPassword"] === "string" && authSection["adminPassword"] ? authSection["adminPassword"] : this.config.adminPassword ?? "",
|
|
9676
|
+
tokenExpiry: typeof authSection["tokenExpiry"] === "string" && authSection["tokenExpiry"] ? authSection["tokenExpiry"] : void 0
|
|
9677
|
+
}, (patch) => {
|
|
9678
|
+
this.ctx.settings?.setSection("auth", patch);
|
|
9679
|
+
});
|
|
9486
9680
|
this.authManager = new AuthManager(reader, this.ctx.logger);
|
|
9487
9681
|
const store = this.ctx.api?.settingsStore;
|
|
9488
9682
|
if (store) {
|