@camstack/system 1.2.443 → 1.2.445
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/assets/record-entries/icon.svg +8 -0
- package/dist/addon-runner.js +81 -42
- package/dist/addon-runner.mjs +82 -43
- package/dist/{agent-https-DlpTMDqA.js → agent-https-CiOW0-sj.js} +810 -12
- package/dist/{agent-https-U0d4uvn2.mjs → agent-https-D4Q8iFNd.mjs} +697 -13
- package/dist/auth/admin-token-manager.d.ts +9 -3
- package/dist/auth/api-key-manager.d.ts +9 -3
- package/dist/auth/auth-audit-log.d.ts +9 -3
- package/dist/auth/device-credential-manager.d.ts +5 -1
- package/dist/auth/external-identity-manager.d.ts +8 -21
- package/dist/auth/login-session-manager.d.ts +11 -3
- package/dist/auth/scoped-token-manager.d.ts +8 -52
- package/dist/auth/totp-manager.d.ts +11 -3
- package/dist/auth/user-manager.d.ts +10 -17
- 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/alert-store.d.ts +32 -0
- package/dist/builtins/alerts/alerts.addon.d.ts +19 -4
- package/dist/builtins/alerts/alerts.addon.js +331 -159
- package/dist/builtins/alerts/alerts.addon.mjs +330 -159
- package/dist/builtins/alerts/record-kinds.d.ts +15 -0
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +1 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +134 -193
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +134 -193
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/record-kinds.d.ts +58 -0
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/seed-marker-store.d.ts +4 -2
- package/dist/builtins/calendars/calendar-prefs-store.d.ts +13 -5
- package/dist/builtins/calendars/calendars.addon.d.ts +2 -2
- package/dist/builtins/calendars/calendars.addon.js +67 -64
- package/dist/builtins/calendars/calendars.addon.mjs +59 -64
- package/dist/builtins/calendars/record-kinds.d.ts +18 -0
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/cluster-agent/record-kinds.d.ts +36 -0
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/block-settings-store.d.ts +8 -4
- package/dist/builtins/core-blocks/core-block-store.d.ts +8 -16
- package/dist/builtins/core-blocks/core-blocks.addon.js +85 -112
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +86 -113
- package/dist/builtins/core-blocks/index.mjs +1 -1
- package/dist/builtins/core-blocks/record-kinds.d.ts +26 -0
- package/dist/builtins/device-manager/device-manager.addon.js +111 -187
- package/dist/builtins/device-manager/device-manager.addon.mjs +110 -187
- package/dist/builtins/device-manager/device-tombstone-store.d.ts +9 -48
- package/dist/builtins/device-manager/record-kinds.d.ts +14 -0
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +152 -22
- package/dist/builtins/keychain/index.mjs +152 -22
- package/dist/builtins/keychain/keychain-service.d.ts +3 -2
- package/dist/builtins/keychain/keychain-store.d.ts +13 -2
- package/dist/builtins/keychain/record-kinds.d.ts +16 -0
- 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-schema.d.ts +3 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2903 -2123
- package/dist/builtins/local-auth/local-auth.addon.mjs +2904 -2124
- package/dist/builtins/local-auth/oauth-session-manager.d.ts +8 -48
- package/dist/builtins/local-auth/record-kinds.d.ts +141 -0
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- 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/record-entries/entries-service.d.ts +42 -0
- package/dist/builtins/record-entries/index.d.ts +1 -0
- package/dist/builtins/record-entries/index.js +142 -0
- package/dist/builtins/record-entries/index.mjs +136 -0
- package/dist/builtins/record-entries/record-entries.addon.d.ts +13 -0
- package/dist/builtins/records/legacy-table-row-count.d.ts +5 -0
- package/dist/builtins/records/phase6-declare-gate.d.ts +28 -0
- package/dist/builtins/records-isolated.d.ts +10 -0
- 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/file-host-client.d.ts +2 -0
- package/dist/builtins/sqlite-storage/file-host-handlers.d.ts +4 -0
- package/dist/builtins/sqlite-storage/file-host-protocol.d.ts +7 -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/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/integration-record-kinds.d.ts +30 -0
- package/dist/builtins/sqlite-storage/integration-registry.d.ts +10 -16
- package/dist/builtins/sqlite-storage/owned-sqlite-file.d.ts +7 -0
- package/dist/builtins/sqlite-storage/placement-router.d.ts +5 -0
- package/dist/builtins/sqlite-storage/records/count-settings-array-legacy.d.ts +5 -0
- package/dist/builtins/sqlite-storage/records/count-settings-brokers-legacy.d.ts +6 -0
- package/dist/builtins/sqlite-storage/records/records-catalog.d.ts +29 -0
- package/dist/builtins/sqlite-storage/records/records-engine-types.d.ts +51 -0
- package/dist/builtins/sqlite-storage/records/records-engine.d.ts +94 -0
- package/dist/builtins/sqlite-storage/records/records-explain.d.ts +18 -0
- package/dist/builtins/sqlite-storage/records/records-plan.d.ts +90 -0
- package/dist/builtins/sqlite-storage/records/records-probe.d.ts +33 -0
- package/dist/builtins/sqlite-storage/records/records-provider.d.ts +63 -0
- package/dist/builtins/sqlite-storage/records/records-rows.d.ts +46 -0
- package/dist/builtins/sqlite-storage/records/records-sql.d.ts +41 -0
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +17 -10
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +8 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +446 -5
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +446 -5
- package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +15 -1
- package/dist/builtins/storage-orchestrator/drain-state-store.d.ts +5 -2
- package/dist/builtins/storage-orchestrator/location-store.d.ts +7 -2
- package/dist/builtins/storage-orchestrator/record-kinds.d.ts +38 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +2 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +196 -5
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +195 -6
- package/dist/builtins/system-config/record-kinds.d.ts +32 -0
- package/dist/builtins/system-config/system-config.addon.js +53 -618
- package/dist/builtins/system-config/system-config.addon.mjs +29 -577
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-C8tUG2uL.mjs → composition-sources-BMt5cFYb.mjs} +1 -1
- package/dist/{composition-sources-BUXX1e8j.js → composition-sources-D3fi9Xns.js} +1 -1
- package/dist/{constants-CGwVaAV3.mjs → constants-BMHCxRzb.mjs} +1 -1
- package/dist/{constants-DWmm7_of.js → constants-Br879Axi.js} +1 -1
- package/dist/{device-ca-DGayRmC0.js → device-ca-CnJ_va7i.js} +1 -1
- package/dist/{device-ca-DBfiJ_SB.mjs → device-ca-T8osSMos.mjs} +1 -1
- package/dist/{dist-Bxt_S-9a.mjs → dist-BNunRyXT.mjs} +1133 -93
- package/dist/{dist-D9qT3jHr.js → dist-DgOG8flk.js} +1354 -92
- package/dist/file-host-worker.js +11 -1
- package/dist/file-host-worker.mjs +11 -1
- package/dist/{hub-mdns-ciao-B-wk9nzx.js → hub-mdns-ciao-BIkTHq-n.js} +2 -2
- package/dist/{hub-mdns-ciao-DpPcQDg-.mjs → hub-mdns-ciao-D16oRQ9K.mjs} +2 -2
- package/dist/index.d.ts +7 -0
- package/dist/index.js +3111 -2806
- package/dist/index.mjs +3083 -2795
- package/dist/kernel/index.d.ts +2 -0
- package/dist/kernel/moleculer/event-bus.d.ts +3 -1
- package/dist/kernel/moleculer/mesh-mtls/mesh-certificate-registry.d.ts +5 -1
- package/dist/kernel/moleculer/records-api-transport.d.ts +9 -0
- package/dist/kernel/moleculer/remote-logger.d.ts +2 -2
- package/dist/kernel/settings-view-types.d.ts +0 -7
- package/dist/kernel/transport/cap-route-resolver.d.ts +9 -38
- package/dist/phase6-declare-gate-Ci1-8uUn.js +98 -0
- package/dist/phase6-declare-gate-tkKOEitw.mjs +93 -0
- package/dist/read-all-rows-CVoO1ONM.js +29 -0
- package/dist/read-all-rows-TaPqdWNF.mjs +25 -0
- package/dist/records/read-all-rows.d.ts +6 -0
- package/dist/{restore-archive-9CGgeBzD.mjs → restore-archive-DR9MtO7J.mjs} +339 -9
- package/dist/{restore-archive-BMNXwWWD.js → restore-archive-DjJnCgap.js} +353 -5
- package/dist/tls/agent-https-names.d.ts +9 -13
- package/dist/{wal-maintenance-cRHR4rUY.js → wal-maintenance-CODGqhKY.js} +0 -0
- package/dist/{wal-maintenance-sIB32ONp.mjs → wal-maintenance-CfvgtQ7C.mjs} +0 -0
- package/package.json +22 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CollectionColumn, SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import type { CollectionColumn, RecordKindHandle, SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { AdminTokenBody } from "../builtins/local-auth/record-kinds.js";
|
|
2
3
|
/**
|
|
3
4
|
* @durable class=config owner=local-auth
|
|
4
5
|
* write="an admin creates a token (after re-authentication); `lastUsedAt` is
|
|
@@ -19,10 +20,15 @@ export interface AdminTokenRecord {
|
|
|
19
20
|
readonly lastUsedAt: number | null;
|
|
20
21
|
readonly revokedAt: number | null;
|
|
21
22
|
}
|
|
23
|
+
export interface AdminTokenRecordsDeps {
|
|
24
|
+
readonly adminTokensKind: RecordKindHandle<AdminTokenBody>;
|
|
25
|
+
readonly store?: SettingsStoreClient;
|
|
26
|
+
}
|
|
22
27
|
export declare class AdminTokenManager {
|
|
23
|
-
private readonly store;
|
|
24
28
|
private readonly now;
|
|
25
|
-
|
|
29
|
+
private readonly kind;
|
|
30
|
+
private readonly store;
|
|
31
|
+
constructor(deps: SettingsStoreClient | AdminTokenRecordsDeps, now?: () => number);
|
|
26
32
|
/** Mint a token for `createdBy`. Refuses an expiry in the past or past 90 days. */
|
|
27
33
|
create(input: {
|
|
28
34
|
readonly createdBy: string;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import type { ApiKeyRecord, SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import type { ApiKeyRecord, RecordKindHandle, SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { ApiKeyBody } from "../builtins/local-auth/record-kinds.js";
|
|
2
3
|
export type { ApiKeyRecord };
|
|
3
4
|
export interface ApiKeyStorageAccess {
|
|
4
5
|
getStore(): SettingsStoreClient;
|
|
5
6
|
}
|
|
7
|
+
export interface ApiKeyRecordsDeps {
|
|
8
|
+
readonly apiKeysKind: RecordKindHandle<ApiKeyBody>;
|
|
9
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
10
|
+
}
|
|
6
11
|
export declare class ApiKeyManager {
|
|
7
|
-
private readonly
|
|
8
|
-
|
|
12
|
+
private readonly kind;
|
|
13
|
+
private readonly legacyStore;
|
|
14
|
+
constructor(deps: ApiKeyStorageAccess | ApiKeyRecordsDeps);
|
|
9
15
|
private get store();
|
|
10
16
|
listAll(): Promise<Omit<ApiKeyRecord, "tokenHash">[]>;
|
|
11
17
|
revoke(id: string): Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CollectionColumn, IScopedLogger, SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import type { CollectionColumn, IScopedLogger, RecordKindHandle, SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { AuthAuditBody } from "../builtins/local-auth/record-kinds.js";
|
|
2
3
|
/**
|
|
3
4
|
* @durable class=ledger owner=local-auth
|
|
4
5
|
* write="one row per audited auth event: a second factor skipped from a trusted
|
|
@@ -22,11 +23,16 @@ export interface AuthAuditRecord extends AuthAuditEvent {
|
|
|
22
23
|
readonly id: string;
|
|
23
24
|
readonly at: number;
|
|
24
25
|
}
|
|
26
|
+
export interface AuthAuditRecordsDeps {
|
|
27
|
+
readonly authAuditKind: RecordKindHandle<AuthAuditBody>;
|
|
28
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
29
|
+
}
|
|
25
30
|
export declare class AuthAuditLog {
|
|
26
|
-
private readonly store;
|
|
27
31
|
private readonly logger;
|
|
28
32
|
private readonly now;
|
|
29
|
-
|
|
33
|
+
private readonly kind;
|
|
34
|
+
private readonly store;
|
|
35
|
+
constructor(deps: SettingsStoreClient | AuthAuditRecordsDeps, logger?: IScopedLogger | null, now?: () => number);
|
|
30
36
|
/** Record `event`. Never throws. */
|
|
31
37
|
record(event: AuthAuditEvent): Promise<void>;
|
|
32
38
|
/** Newest first, at most `limit` (≤ 500), optionally one user's. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CollectionColumn, IScopedLogger, SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import type { CollectionColumn, IScopedLogger, RecordKindHandle, SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { DeviceCredentialBody } from "../builtins/local-auth/record-kinds.js";
|
|
2
3
|
import { type DeviceCredential, type DevicePlatform, type DeviceSignaturePurpose } from "@camstack/types";
|
|
3
4
|
import type { DeviceCaStore } from "./device-ca-store.js";
|
|
4
5
|
/**
|
|
@@ -70,6 +71,7 @@ export interface DeviceCredentialManagerDeps {
|
|
|
70
71
|
} | null>;
|
|
71
72
|
/** Hub-wide switch for `enrollSelf`; absent = allowed. */
|
|
72
73
|
readonly selfEnrollmentAllowed: () => Promise<boolean>;
|
|
74
|
+
readonly deviceCredentialsKind?: RecordKindHandle<DeviceCredentialBody> | null;
|
|
73
75
|
readonly now?: () => number;
|
|
74
76
|
readonly logger?: IScopedLogger;
|
|
75
77
|
}
|
|
@@ -148,6 +150,8 @@ export declare class DeviceCredentialManager {
|
|
|
148
150
|
toSummary(record: DeviceCredentialRecord, username: string | null): DeviceCredential;
|
|
149
151
|
/** Delete rows revoked or expired more than 90 days ago. */
|
|
150
152
|
reap(): Promise<number>;
|
|
153
|
+
private persistRecord;
|
|
154
|
+
private deleteRecord;
|
|
151
155
|
private save;
|
|
152
156
|
private refuse;
|
|
153
157
|
private prune;
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External sign-in identities linked to local users (D782).
|
|
3
|
-
*
|
|
4
|
-
* An OIDC login names an identity `(provider, subject)` — the provider
|
|
5
|
-
* instance's login-method id (`auth-oidc/authentik`) and the IdP's `sub`. It
|
|
6
|
-
* signs in ONLY the user its owner explicitly linked it to: no
|
|
7
|
-
* auto-provisioning, no email matching, no group mapping.
|
|
8
|
-
*
|
|
9
|
-
* The row id is the identity itself (`JSON.stringify([provider, subject])`),
|
|
10
|
-
* so the collection's primary key is what makes "one identity → one user" a
|
|
11
|
-
* storage invariant rather than a check that a race could slip past.
|
|
12
3
|
*/
|
|
13
|
-
import type { SettingsStoreClient } from "@camstack/types";
|
|
4
|
+
import type { RecordKindHandle, SettingsStoreClient } from "@camstack/types";
|
|
5
|
+
import type { ExternalIdentityBody } from "../builtins/local-auth/record-kinds.js";
|
|
14
6
|
export interface ExternalIdentityRecord {
|
|
15
7
|
readonly provider: string;
|
|
16
8
|
readonly subject: string;
|
|
17
|
-
/** Verified `iss` the identity was linked under. */
|
|
18
9
|
readonly issuer: string;
|
|
19
10
|
readonly userId: string;
|
|
20
11
|
readonly label?: string;
|
|
@@ -24,32 +15,28 @@ export interface ExternalIdentityKey {
|
|
|
24
15
|
readonly provider: string;
|
|
25
16
|
readonly subject: string;
|
|
26
17
|
}
|
|
27
|
-
/** The identity is already linked to a different user. */
|
|
28
18
|
export declare class ExternalIdentityConflictError extends Error {
|
|
29
19
|
constructor();
|
|
30
20
|
}
|
|
21
|
+
export interface ExternalIdentityRecordsDeps {
|
|
22
|
+
readonly identitiesKind: RecordKindHandle<ExternalIdentityBody>;
|
|
23
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
24
|
+
}
|
|
31
25
|
export declare class ExternalIdentityManager {
|
|
26
|
+
private readonly kind;
|
|
32
27
|
private readonly store;
|
|
33
|
-
constructor(
|
|
28
|
+
constructor(deps: SettingsStoreClient | ExternalIdentityRecordsDeps);
|
|
34
29
|
private find;
|
|
35
|
-
/** The link of `(provider, subject)`, or `null`. */
|
|
36
30
|
findLink(provider: string, subject: string): Promise<ExternalIdentityRecord | null>;
|
|
37
|
-
/** The user `(provider, subject)` is linked to, or `null`. */
|
|
38
31
|
findUser(provider: string, subject: string): Promise<string | null>;
|
|
39
32
|
listForUser(userId: string): Promise<readonly ExternalIdentityRecord[]>;
|
|
40
|
-
/**
|
|
41
|
-
* Link `(provider, subject)` to `userId`. Idempotent for the same user;
|
|
42
|
-
* {@link ExternalIdentityConflictError} when another user holds it.
|
|
43
|
-
*/
|
|
44
33
|
link(input: ExternalIdentityKey & {
|
|
45
34
|
userId: string;
|
|
46
35
|
issuer: string;
|
|
47
36
|
label?: string;
|
|
48
37
|
}): Promise<void>;
|
|
49
|
-
/** Remove one link of `userId`; `false` when that user did not hold it. */
|
|
50
38
|
unlink(input: ExternalIdentityKey & {
|
|
51
39
|
userId: string;
|
|
52
40
|
}): Promise<boolean>;
|
|
53
|
-
/** Delete every link of a user being deleted. Returns how many were removed. */
|
|
54
41
|
removeAllForUser(userId: string): Promise<number>;
|
|
55
42
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CollectionColumn, IScopedLogger, SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import type { CollectionColumn, IScopedLogger, RecordKindHandle, SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { LoginSessionBody, LoginSessionCutoffBody } from "../builtins/local-auth/record-kinds.js";
|
|
2
3
|
/**
|
|
3
4
|
* @durable class=ledger owner=local-auth
|
|
4
5
|
* write="one row per login (password, passkey, SSO, handoff, session exchange);
|
|
@@ -73,15 +74,22 @@ export interface LoginSessionManagerOptions {
|
|
|
73
74
|
readonly now?: () => number;
|
|
74
75
|
readonly logger?: IScopedLogger;
|
|
75
76
|
}
|
|
77
|
+
export interface LoginSessionRecordsDeps {
|
|
78
|
+
readonly sessionsKind: RecordKindHandle<LoginSessionBody>;
|
|
79
|
+
readonly cutoffsKind: RecordKindHandle<LoginSessionCutoffBody>;
|
|
80
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
81
|
+
}
|
|
76
82
|
export declare class LoginSessionManager {
|
|
77
|
-
private readonly store;
|
|
78
83
|
private readonly sessions;
|
|
79
84
|
/** refresh hash (current or previous) → session id */
|
|
80
85
|
private readonly byRefreshHash;
|
|
81
86
|
private readonly cutoffs;
|
|
82
87
|
private readonly now;
|
|
83
88
|
private readonly logger;
|
|
84
|
-
|
|
89
|
+
private readonly sessionsKind;
|
|
90
|
+
private readonly cutoffsKind;
|
|
91
|
+
private readonly store;
|
|
92
|
+
constructor(deps: SettingsStoreClient | LoginSessionRecordsDeps, options?: LoginSessionManagerOptions);
|
|
85
93
|
/** Load every row into the mirror. Call once at init, before serving. */
|
|
86
94
|
load(): Promise<void>;
|
|
87
95
|
create(input: CreateLoginSessionInput): Promise<{
|
|
@@ -1,69 +1,25 @@
|
|
|
1
|
-
import type { ScopedToken, TokenScope, SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import type { RecordKindHandle, ScopedToken, TokenScope, SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { ScopedTokenBody } from "../builtins/local-auth/record-kinds.js";
|
|
3
|
+
export interface ScopedTokenRecordsDeps {
|
|
4
|
+
readonly scopedTokensKind: RecordKindHandle<ScopedTokenBody>;
|
|
5
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
8
|
* Manages scoped API tokens with restricted addon/route/capability access.
|
|
4
9
|
*/
|
|
5
10
|
export declare class ScopedTokenManager {
|
|
11
|
+
private readonly kind;
|
|
6
12
|
private readonly store;
|
|
7
|
-
constructor(
|
|
13
|
+
constructor(deps: SettingsStoreClient | ScopedTokenRecordsDeps);
|
|
8
14
|
create(userId: string, name: string, scopes: TokenScope[], expiresAt?: number): Promise<{
|
|
9
15
|
token: string;
|
|
10
16
|
record: ScopedToken;
|
|
11
17
|
}>;
|
|
12
18
|
validate(rawToken: string): Promise<ScopedToken | null>;
|
|
13
|
-
/**
|
|
14
|
-
* Coarse scope match — checks only `addonId` / `capability` (no
|
|
15
|
-
* `route-prefix` after the caps-only migration). Used by addon-route
|
|
16
|
-
* HTTP handlers that need a quick allow/deny before the per-method
|
|
17
|
-
* `access` check kicks in via `METHOD_ACCESS_MAP` in
|
|
18
|
-
* `protectedProcedure`.
|
|
19
|
-
*/
|
|
20
19
|
matchesScope(token: ScopedToken, addonId?: string, capability?: string): boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Delete the token row. `true` when a row was removed; `false` when the id
|
|
23
|
-
* was already gone (unknown or previously revoked).
|
|
24
|
-
*/
|
|
25
20
|
revoke(tokenId: string): Promise<boolean>;
|
|
26
21
|
listForUser(userId: string): Promise<ScopedToken[]>;
|
|
27
22
|
updateLastUsed(tokenId: string): Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
* Delete tokens whose expiry has passed.
|
|
30
|
-
*
|
|
31
|
-
* These were never usable — {@link validate} already rejects an expired
|
|
32
|
-
* token — so this is hygiene rather than a hole being closed, and it is
|
|
33
|
-
* worth being precise about what it actually buys:
|
|
34
|
-
*
|
|
35
|
-
* - `listForUser` returns rows with no expiry filter, so the operator's
|
|
36
|
-
* token list showed dead tokens as if they were live. There was no way to
|
|
37
|
-
* tell from the UI which ones still worked.
|
|
38
|
-
* - a database that outlives its tokens keeps their hashes indefinitely.
|
|
39
|
-
* 27 rows on the live hub had been unusable for months.
|
|
40
|
-
*
|
|
41
|
-
* A token with NO expiry (`expiresAt` null/absent) is a deliberate
|
|
42
|
-
* never-expires token and MUST survive: `BETWEEN` never matches NULL in
|
|
43
|
-
* SQL, which is the property this depends on and the spec pins against a
|
|
44
|
-
* real SQLite.
|
|
45
|
-
*
|
|
46
|
-
* The bound is `nowMs - 1` because {@link validate} treats `now ===
|
|
47
|
-
* expiresAt` as still valid; reaping at exactly the expiry instant would
|
|
48
|
-
* delete a token that the same millisecond still accepts.
|
|
49
|
-
*
|
|
50
|
-
* Returns how many rows went.
|
|
51
|
-
*/
|
|
52
23
|
reapExpired(nowMs?: number): Promise<number>;
|
|
53
|
-
/**
|
|
54
|
-
* One-shot migration: drop tokens whose owner can't be resolved.
|
|
55
|
-
*
|
|
56
|
-
* Two ways a token can end up orphan:
|
|
57
|
-
* • Pre-fix tokens minted via the CLI were owned by the literal
|
|
58
|
-
* string `"system"` (provider hardcode, fixed 2026-05-11).
|
|
59
|
-
* • A user gets deleted but their tokens were not cascade-revoked.
|
|
60
|
-
*
|
|
61
|
-
* Either way the UI's `listScopedTokens({ userId: u.id })` never
|
|
62
|
-
* returns them, so the operator can't revoke through the normal flow.
|
|
63
|
-
* We sweep both classes by passing the live user-id set in.
|
|
64
|
-
*
|
|
65
|
-
* Idempotent: if no orphans exist the method is a no-op.
|
|
66
|
-
* Returns the number of tokens removed.
|
|
67
|
-
*/
|
|
68
24
|
cleanupOrphans(validUserIds: ReadonlySet<string>): Promise<number>;
|
|
69
25
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type RawSecretMigrationReport, type IScopedLogger, type SecretsAccess, type SettingsStoreClient } from "@camstack/types";
|
|
1
|
+
import { type RawSecretMigrationReport, type IScopedLogger, type RecordKindHandle, type SecretsAccess, type SettingsStoreClient } from "@camstack/types";
|
|
2
|
+
import type { UserTotpBody } from "../builtins/local-auth/record-kinds.js";
|
|
2
3
|
/**
|
|
3
4
|
* The seed cannot be used right now. The message is what a not-yet-logged-in
|
|
4
5
|
* caller sees, so it is generic; `reason` (keychain detail) is for the server log only.
|
|
@@ -19,16 +20,21 @@ export interface TotpStatus {
|
|
|
19
20
|
readonly enabled: boolean;
|
|
20
21
|
readonly confirmedAt: number | null;
|
|
21
22
|
}
|
|
23
|
+
export interface TotpRecordsDeps {
|
|
24
|
+
readonly userTotpKind: RecordKindHandle<UserTotpBody>;
|
|
25
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
26
|
+
}
|
|
22
27
|
export declare class TotpManager {
|
|
23
|
-
private readonly store;
|
|
24
28
|
/** ±N steps of clock-skew tolerance, expressed in seconds for otplib v13's
|
|
25
29
|
* per-call `epochTolerance`. Default window 1 = ±30 s. */
|
|
26
30
|
private readonly epochTolerance;
|
|
27
31
|
private readonly secrets;
|
|
28
32
|
private readonly logger;
|
|
33
|
+
private readonly userTotpKind;
|
|
34
|
+
private readonly store;
|
|
29
35
|
/** Per-user queue: setup / confirm / disable / migration never interleave on one user. */
|
|
30
36
|
private readonly chains;
|
|
31
|
-
constructor(
|
|
37
|
+
constructor(deps: SettingsStoreClient | TotpRecordsDeps, opts?: {
|
|
32
38
|
/** ±N 30-second windows tolerated. Default 1 = ±30 s clock skew. */
|
|
33
39
|
readonly window?: number;
|
|
34
40
|
/** Keychain handle for owner `system`; `null` = no keychain door (setup refuses). */
|
|
@@ -96,4 +102,6 @@ export declare class TotpManager {
|
|
|
96
102
|
private moveRow;
|
|
97
103
|
private readAll;
|
|
98
104
|
private find;
|
|
105
|
+
private writeRow;
|
|
106
|
+
private removeRow;
|
|
99
107
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { SettingsStoreClient, TokenScope, UserRecord } from "@camstack/types";
|
|
1
|
+
import type { RecordKindHandle, SettingsStoreClient, TokenScope, UserRecord } from "@camstack/types";
|
|
2
2
|
import type { AuthManager } from "./auth-manager.js";
|
|
3
|
+
import type { UserBody } from "../builtins/local-auth/record-kinds.js";
|
|
3
4
|
export type { UserRecord };
|
|
4
5
|
interface CreateUserInput {
|
|
5
6
|
username: string;
|
|
@@ -39,10 +40,17 @@ export type AdminSeedOutcome = {
|
|
|
39
40
|
export interface UserStorageAccess {
|
|
40
41
|
getStore(): SettingsStoreClient;
|
|
41
42
|
}
|
|
43
|
+
export interface UserRecordsDeps {
|
|
44
|
+
readonly usersKind: RecordKindHandle<UserBody>;
|
|
45
|
+
/** Optional legacy store for tests that assert no declareCollection. */
|
|
46
|
+
readonly legacyStore?: SettingsStoreClient;
|
|
47
|
+
}
|
|
42
48
|
export declare class UserManager {
|
|
43
49
|
private readonly storageAccess;
|
|
44
50
|
private readonly auth;
|
|
45
|
-
|
|
51
|
+
private readonly usersKind;
|
|
52
|
+
private readonly legacyStore;
|
|
53
|
+
constructor(storageAccess: UserStorageAccess | UserRecordsDeps, auth: AuthManager);
|
|
46
54
|
private get store();
|
|
47
55
|
create(input: CreateUserInput): Promise<UserRecord>;
|
|
48
56
|
findByUsername(username: string): Promise<UserRecord | null>;
|
|
@@ -55,22 +63,7 @@ export declare class UserManager {
|
|
|
55
63
|
/**
|
|
56
64
|
* Seed {@link FIRST_BOOT_ADMIN_USERNAME} / {@link FIRST_BOOT_ADMIN_PASSWORD}
|
|
57
65
|
* — on FIRST boot only, i.e. when no admin account exists.
|
|
58
|
-
*
|
|
59
|
-
* The seed is never an authority. Once any admin exists, this never writes a
|
|
60
|
-
* password: the operator's own change in the admin UI is the truth from then
|
|
61
|
-
* on (D728). This method once compared the stored hash with a configured
|
|
62
|
-
* password on every boot and rewrote it when they differed, so a password
|
|
63
|
-
* changed in the UI went back at the next restart.
|
|
64
|
-
*
|
|
65
|
-
* `resetPassword: true` is the one explicit exception — the operator's
|
|
66
|
-
* one-shot recovery request (`RESET_ADMIN_PASSWORD`, see
|
|
67
|
-
* `admin-account-boot.ts`): the `admin` user's password goes back to
|
|
68
|
-
* `changeme`, and the next sign-in forces a change again.
|
|
69
66
|
*/
|
|
70
67
|
ensureAdminExists(options?: EnsureAdminOptions): Promise<AdminSeedOutcome>;
|
|
71
|
-
/**
|
|
72
|
-
* Does `username` still sign in with `password`? A hash comparison — the
|
|
73
|
-
* password is never logged or stored. `false` when the user does not exist.
|
|
74
|
-
*/
|
|
75
68
|
hasPassword(username: string, password: string): Promise<boolean>;
|
|
76
69
|
}
|
|
@@ -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-DgOG8flk.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 {
|
|
1
|
+
import { Lr as errMsg, Rr as BaseAddon, la as EventCategory, lt as addonPagesCapability } from "../../dist-BNunRyXT.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-DgOG8flk.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 {
|
|
1
|
+
import { Lr as errMsg, Rr as BaseAddon, dt as addonWidgetsCapability, la as EventCategory } from "../../dist-BNunRyXT.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";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alert persistence over the `alerts` record kind (phase 4) or legacy collection.
|
|
3
|
+
*/
|
|
4
|
+
import type { Alert, RecordKindHandle, RecordsAccess, SettingsStoreClient } from "@camstack/types";
|
|
5
|
+
import { type AlertBody } from "./record-kinds.js";
|
|
6
|
+
export { ALERTS_COLLECTION } from "./record-kinds.js";
|
|
7
|
+
export type AlertRecord = {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly data: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
export declare class AlertStore {
|
|
12
|
+
private readonly kind;
|
|
13
|
+
private readonly legacyStore;
|
|
14
|
+
constructor(kind: RecordKindHandle<AlertBody> | null, legacyStore: SettingsStoreClient | null);
|
|
15
|
+
static of(records: Pick<RecordsAccess, "kind">): AlertStore;
|
|
16
|
+
static legacy(store: SettingsStoreClient): AlertStore;
|
|
17
|
+
private legacyRows;
|
|
18
|
+
list(filter?: {
|
|
19
|
+
unreadOnly?: boolean;
|
|
20
|
+
limit?: number;
|
|
21
|
+
}): Promise<readonly AlertRecord[]>;
|
|
22
|
+
countUnread(): Promise<number>;
|
|
23
|
+
countAll(): Promise<number>;
|
|
24
|
+
getData(id: string): Promise<Record<string, unknown> | null>;
|
|
25
|
+
mergeUpdate(id: string, patch: Record<string, unknown>): Promise<void>;
|
|
26
|
+
persist(alert: Alert): Promise<void>;
|
|
27
|
+
putRaw(id: string, data: Record<string, unknown>): Promise<void>;
|
|
28
|
+
delete(id: string): Promise<void>;
|
|
29
|
+
listAllByCreatedAtAsc(): Promise<readonly AlertRecord[]>;
|
|
30
|
+
listRecent(limit: number): Promise<readonly AlertRecord[]>;
|
|
31
|
+
findWhereDataField(field: string, value: unknown): Promise<readonly AlertRecord[]>;
|
|
32
|
+
}
|
|
@@ -5,10 +5,15 @@ interface AlertCenterConfig {
|
|
|
5
5
|
readonly retentionDays: number;
|
|
6
6
|
/** Push critical system alerts (runner failed/refused, runners degraded) straight to the notifiers (D877). */
|
|
7
7
|
readonly criticalPushEnabled: boolean;
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Notifier target ids for that push (`notification-target-multiselect`).
|
|
10
|
+
* Empty = every enabled operator-level (shared) target. A legacy CSV string
|
|
11
|
+
* still stored in the addon store is accepted at read time.
|
|
12
|
+
*/
|
|
13
|
+
readonly criticalPushTargetIds: readonly string[];
|
|
10
14
|
}
|
|
11
15
|
export declare class AlertCenterAddon extends BaseAddon<AlertCenterConfig> {
|
|
16
|
+
private alertStore;
|
|
12
17
|
private unsubscribers;
|
|
13
18
|
/** How long a burst of critical findings is gathered into one digest push. */
|
|
14
19
|
private readonly pushCoalesceMs;
|
|
@@ -50,6 +55,8 @@ export declare class AlertCenterAddon extends BaseAddon<AlertCenterConfig> {
|
|
|
50
55
|
private readonly pushQueue;
|
|
51
56
|
private pushTimer;
|
|
52
57
|
private pushPolicy;
|
|
58
|
+
/** Rewrite a legacy CSV `criticalPushTargetIds` string into `string[]`. */
|
|
59
|
+
private migrateCriticalPushTargetIds;
|
|
53
60
|
private pushPorts;
|
|
54
61
|
/**
|
|
55
62
|
* Queue a critical finding for the next digest. A burst (every runner of a boot)
|
|
@@ -109,12 +116,20 @@ export declare class AlertCenterAddon extends BaseAddon<AlertCenterConfig> {
|
|
|
109
116
|
/** SystemLivenessRecovered — the invariant holds again; drop the alert. */
|
|
110
117
|
private handleLivenessRecovered;
|
|
111
118
|
/**
|
|
112
|
-
* Stream offline — ONLY `stale-timeout
|
|
113
|
-
*
|
|
119
|
+
* Stream offline — ONLY an outage reason counts: `stale-timeout`, or one of
|
|
120
|
+
* the battery failures (`wake-timeout`, `connection-error`,
|
|
121
|
+
* `battery-unreachable`). Suspend / destroy / idle dial are deliberate and
|
|
122
|
+
* must not ring the bell (same gate NC uses). One card per DEVICE (D883).
|
|
114
123
|
*/
|
|
115
124
|
private handleStreamOffline;
|
|
116
125
|
/** Stream online after an outage — drop the matching offline card. */
|
|
117
126
|
private handleStreamOnline;
|
|
127
|
+
/**
|
|
128
|
+
* Dismiss the pre-D883 per-cam-stream cards (`stream-offline:<deviceId>:<stream>`)
|
|
129
|
+
* of one device, or of every device when none is named. They can never meet
|
|
130
|
+
* their `stream.online` under the per-device id.
|
|
131
|
+
*/
|
|
132
|
+
private dismissLegacyStreamCards;
|
|
118
133
|
private resolveDeviceName;
|
|
119
134
|
private buildMessage;
|
|
120
135
|
private emitAlert;
|