@elizaos/vault 2.0.0-alpha.537
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -0
- package/dist/audit.d.ts +14 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +27 -0
- package/dist/audit.js.map +1 -0
- package/dist/credentials.d.ts +58 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +157 -0
- package/dist/credentials.js.map +1 -0
- package/dist/crypto.d.ts +18 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +67 -0
- package/dist/crypto.js.map +1 -0
- package/dist/external-credentials.d.ts +62 -0
- package/dist/external-credentials.d.ts.map +1 -0
- package/dist/external-credentials.js +335 -0
- package/dist/external-credentials.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +70 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +163 -0
- package/dist/install.js.map +1 -0
- package/dist/inventory.d.ts +140 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +319 -0
- package/dist/inventory.js.map +1 -0
- package/dist/manager.d.ts +161 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +466 -0
- package/dist/manager.js.map +1 -0
- package/dist/master-key.d.ts +86 -0
- package/dist/master-key.d.ts.map +1 -0
- package/dist/master-key.js +247 -0
- package/dist/master-key.js.map +1 -0
- package/dist/password-managers.d.ts +17 -0
- package/dist/password-managers.d.ts.map +1 -0
- package/dist/password-managers.js +59 -0
- package/dist/password-managers.js.map +1 -0
- package/dist/profiles.d.ts +68 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +189 -0
- package/dist/profiles.js.map +1 -0
- package/dist/store.d.ts +22 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +137 -0
- package/dist/store.js.map +1 -0
- package/dist/testing.d.ts +32 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +70 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/vault.d.ts +77 -0
- package/dist/vault.d.ts.map +1 -0
- package/dist/vault.js +269 -0
- package/dist/vault.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { type ExecFn } from "./external-credentials.js";
|
|
2
|
+
import { type ResolutionContext } from "./profiles.js";
|
|
3
|
+
import { type Vault } from "./vault.js";
|
|
4
|
+
/**
|
|
5
|
+
* SecretsManager — the high-level routing layer over Vault.
|
|
6
|
+
*
|
|
7
|
+
* Lets a user pick which backends to enable for sensitive secrets:
|
|
8
|
+
*
|
|
9
|
+
* - "in-house" → Eliza's local store (OS keychain master + AES-GCM file)
|
|
10
|
+
* - "1password" → 1Password CLI (`op`); references stored locally
|
|
11
|
+
* - "protonpass" → Proton Pass (scaffolded; vendor CLI not stable yet)
|
|
12
|
+
* - "bitwarden" → Bitwarden CLI (`bw`); references stored locally
|
|
13
|
+
*
|
|
14
|
+
* Three modes the user can run in:
|
|
15
|
+
*
|
|
16
|
+
* - **None enabled** → only "in-house" is used. Default.
|
|
17
|
+
* - **One enabled** → user picked (e.g.) "1password"; sensitive values
|
|
18
|
+
* route there only when the caller stores an explicit reference.
|
|
19
|
+
* - **All enabled** → user can pick per-key in Settings; unsupported
|
|
20
|
+
* direct external writes fail loudly instead of hiding the problem.
|
|
21
|
+
*
|
|
22
|
+
* The Vault stays the canonical store for non-sensitive config and
|
|
23
|
+
* for the references that point at external password managers.
|
|
24
|
+
*/
|
|
25
|
+
export type BackendId = "in-house" | "1password" | "protonpass" | "bitwarden";
|
|
26
|
+
export interface BackendStatus {
|
|
27
|
+
readonly id: BackendId;
|
|
28
|
+
readonly label: string;
|
|
29
|
+
/** True if the backend is available on this machine. */
|
|
30
|
+
readonly available: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* True if the user is currently authenticated to this backend.
|
|
33
|
+
* Undefined when not applicable (e.g., in-house) or detection
|
|
34
|
+
* isn't supported yet.
|
|
35
|
+
*/
|
|
36
|
+
readonly signedIn?: boolean;
|
|
37
|
+
/** Human-readable detail for display when not fully ready. */
|
|
38
|
+
readonly detail?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Authentication path the backend is using. `desktop-app` means the
|
|
41
|
+
* vendor's desktop app brokers auth (e.g. 1Password 8 native app
|
|
42
|
+
* integration with the `op` CLI), so no session token is required.
|
|
43
|
+
* `session-token` means we authenticated via stored session token.
|
|
44
|
+
* `null` when the backend is unavailable or not signed in.
|
|
45
|
+
*
|
|
46
|
+
* Undefined for backends that don't have multiple auth modes
|
|
47
|
+
* (e.g. in-house, protonpass).
|
|
48
|
+
*/
|
|
49
|
+
readonly authMode?: "desktop-app" | "session-token" | null;
|
|
50
|
+
}
|
|
51
|
+
export interface ManagerPreferences {
|
|
52
|
+
/**
|
|
53
|
+
* Backends the user has enabled, ordered by priority.
|
|
54
|
+
* "in-house" is always available for non-sensitive values, but sensitive
|
|
55
|
+
* values follow this order exactly and fail if the selected backend cannot
|
|
56
|
+
* accept the write.
|
|
57
|
+
*/
|
|
58
|
+
readonly enabled: readonly BackendId[];
|
|
59
|
+
/**
|
|
60
|
+
* Per-key routing overrides. Useful when a user wants e.g. work
|
|
61
|
+
* keys in 1Password and personal keys in Bitwarden.
|
|
62
|
+
*/
|
|
63
|
+
readonly routing?: Readonly<Record<string, BackendId>>;
|
|
64
|
+
}
|
|
65
|
+
export declare const DEFAULT_PREFERENCES: ManagerPreferences;
|
|
66
|
+
export interface ManagerSetOptions {
|
|
67
|
+
readonly sensitive?: boolean;
|
|
68
|
+
/** Force routing to a specific backend, overriding preferences. */
|
|
69
|
+
readonly store?: BackendId;
|
|
70
|
+
readonly caller?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface SecretsManager {
|
|
73
|
+
/** The underlying vault. Use directly for advanced cases. */
|
|
74
|
+
readonly vault: Vault;
|
|
75
|
+
/** Set a value, routing per the user's preferences. */
|
|
76
|
+
set(key: string, value: string, opts?: ManagerSetOptions): Promise<void>;
|
|
77
|
+
/** Get a value, resolving through whatever backend it's stored in. */
|
|
78
|
+
get(key: string): Promise<string>;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve a value through the profile + per-context routing layer.
|
|
81
|
+
*
|
|
82
|
+
* Resolution order:
|
|
83
|
+
* 1. Per-context routing rule that matches `ctx`
|
|
84
|
+
* 2. The key's `_meta.<key>.activeProfile`
|
|
85
|
+
* 3. The global `_routing.config.defaultProfile`
|
|
86
|
+
* 4. The bare key value (legacy path)
|
|
87
|
+
*
|
|
88
|
+
* For keys without any meta entry, this is identical to `get()`.
|
|
89
|
+
*/
|
|
90
|
+
getActive(key: string, ctx?: ResolutionContext): Promise<string>;
|
|
91
|
+
/** Existence check. */
|
|
92
|
+
has(key: string): Promise<boolean>;
|
|
93
|
+
/** Remove (clears the local entry; doesn't delete from external password manager). */
|
|
94
|
+
remove(key: string): Promise<void>;
|
|
95
|
+
/** List keys. */
|
|
96
|
+
list(prefix?: string): Promise<readonly string[]>;
|
|
97
|
+
/** Probe each known backend; returns availability + sign-in status. */
|
|
98
|
+
detectBackends(): Promise<readonly BackendStatus[]>;
|
|
99
|
+
/** Read the user's saved preferences. */
|
|
100
|
+
getPreferences(): Promise<ManagerPreferences>;
|
|
101
|
+
/** Save the user's preferences. Persisted to the vault. */
|
|
102
|
+
setPreferences(prefs: ManagerPreferences): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* List saved logins from every available source: in-house vault always,
|
|
105
|
+
* plus 1Password and Bitwarden when they're signed in.
|
|
106
|
+
*
|
|
107
|
+
* Per-backend errors are collected into `failures` rather than thrown —
|
|
108
|
+
* a flaky external CLI must not block the in-house list.
|
|
109
|
+
*/
|
|
110
|
+
listAllSavedLogins(opts?: ListAllSavedLoginsOptions): Promise<UnifiedLoginListResult>;
|
|
111
|
+
/** Reveal a single login (full credentials) from the indicated source. */
|
|
112
|
+
revealSavedLogin(source: "in-house" | "1password" | "bitwarden", identifier: string): Promise<UnifiedLoginReveal>;
|
|
113
|
+
}
|
|
114
|
+
export interface CreateManagerOptions {
|
|
115
|
+
/** Provide your own Vault. Default: `createVault()`. */
|
|
116
|
+
readonly vault?: Vault;
|
|
117
|
+
/**
|
|
118
|
+
* Subprocess executor for password-manager CLIs. Tests inject a stub.
|
|
119
|
+
* Defaults to a real `child_process.execFile`-based runner.
|
|
120
|
+
*/
|
|
121
|
+
readonly exec?: ExecFn;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Source-tagged saved-login summary spanning every backend.
|
|
125
|
+
*
|
|
126
|
+
* `identifier`:
|
|
127
|
+
* - `in-house` → `<domain>:<username>` (matches the route shape used
|
|
128
|
+
* to delete + reveal a single in-house credential)
|
|
129
|
+
* - `1password` → the 1Password item id (op_uuid)
|
|
130
|
+
* - `bitwarden` → the Bitwarden item id (uuid)
|
|
131
|
+
*/
|
|
132
|
+
export interface UnifiedLoginListEntry {
|
|
133
|
+
readonly source: "in-house" | "1password" | "bitwarden";
|
|
134
|
+
readonly identifier: string;
|
|
135
|
+
readonly domain: string | null;
|
|
136
|
+
readonly username: string;
|
|
137
|
+
/** Display name. For in-house this == username; external == op/bw title. */
|
|
138
|
+
readonly title: string;
|
|
139
|
+
readonly updatedAt: number;
|
|
140
|
+
}
|
|
141
|
+
export interface UnifiedLoginReveal {
|
|
142
|
+
readonly source: "in-house" | "1password" | "bitwarden";
|
|
143
|
+
readonly identifier: string;
|
|
144
|
+
readonly username: string;
|
|
145
|
+
readonly password: string;
|
|
146
|
+
readonly totp?: string;
|
|
147
|
+
readonly domain: string | null;
|
|
148
|
+
}
|
|
149
|
+
export interface UnifiedLoginListResult {
|
|
150
|
+
readonly logins: readonly UnifiedLoginListEntry[];
|
|
151
|
+
/** Per-backend errors. The list still returns whatever succeeded. */
|
|
152
|
+
readonly failures: ReadonlyArray<{
|
|
153
|
+
readonly source: "1password" | "bitwarden";
|
|
154
|
+
readonly message: string;
|
|
155
|
+
}>;
|
|
156
|
+
}
|
|
157
|
+
export interface ListAllSavedLoginsOptions {
|
|
158
|
+
readonly domain?: string;
|
|
159
|
+
}
|
|
160
|
+
export declare function createManager(opts?: CreateManagerOptions): SecretsManager;
|
|
161
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/manager.js
ADDED
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { listSavedLogins, getSavedLogin, } from "./credentials.js";
|
|
4
|
+
import { defaultExecFn, listBitwardenLogins, listOnePasswordLogins, revealBitwardenLogin, revealOnePasswordLogin, } from "./external-credentials.js";
|
|
5
|
+
import { resolveActiveValue } from "./profiles.js";
|
|
6
|
+
import { createVault, VaultMissError } from "./vault.js";
|
|
7
|
+
const exec = promisify(execFile);
|
|
8
|
+
export const DEFAULT_PREFERENCES = {
|
|
9
|
+
enabled: ["in-house"],
|
|
10
|
+
};
|
|
11
|
+
export function createManager(opts = {}) {
|
|
12
|
+
const vault = opts.vault ?? createVault();
|
|
13
|
+
const execFn = opts.exec ?? defaultExecFn();
|
|
14
|
+
return new ManagerImpl(vault, execFn);
|
|
15
|
+
}
|
|
16
|
+
const PREFERENCES_KEY = "_manager.preferences";
|
|
17
|
+
class ManagerImpl {
|
|
18
|
+
vault;
|
|
19
|
+
execFn;
|
|
20
|
+
constructor(vault, execFn) {
|
|
21
|
+
this.vault = vault;
|
|
22
|
+
this.execFn = execFn;
|
|
23
|
+
}
|
|
24
|
+
async getPreferences() {
|
|
25
|
+
try {
|
|
26
|
+
const raw = await this.vault.get(PREFERENCES_KEY);
|
|
27
|
+
const parsed = JSON.parse(raw);
|
|
28
|
+
return normalizePreferences(parsed);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (err instanceof VaultMissError) {
|
|
32
|
+
return DEFAULT_PREFERENCES;
|
|
33
|
+
}
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async setPreferences(prefs) {
|
|
38
|
+
const normalized = normalizePreferences(prefs);
|
|
39
|
+
// Encrypt at rest. The `routing` map can contain password-manager item
|
|
40
|
+
// paths (e.g. "Personal/OpenRouter/api-key") which are internal-disclosure
|
|
41
|
+
// information; storing them as a plain `kind: "value"` entry would write
|
|
42
|
+
// those paths to vault.json in clear text.
|
|
43
|
+
await this.vault.set(PREFERENCES_KEY, JSON.stringify(normalized), {
|
|
44
|
+
sensitive: true,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async set(key, value, opts = {}) {
|
|
48
|
+
const target = await this.resolveTargetBackend(key, opts);
|
|
49
|
+
if (target === "in-house") {
|
|
50
|
+
await this.vault.set(key, value, {
|
|
51
|
+
...(opts.sensitive ? { sensitive: true } : {}),
|
|
52
|
+
...(opts.caller ? { caller: opts.caller } : {}),
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`manager.set: backend "${target}" cannot accept direct writes yet. Store the secret in that password manager first and save a reference explicitly.`);
|
|
57
|
+
}
|
|
58
|
+
async get(key) {
|
|
59
|
+
return this.vault.get(key);
|
|
60
|
+
}
|
|
61
|
+
async getActive(key, ctx) {
|
|
62
|
+
return resolveActiveValue(this.vault, key, ctx);
|
|
63
|
+
}
|
|
64
|
+
async has(key) {
|
|
65
|
+
return this.vault.has(key);
|
|
66
|
+
}
|
|
67
|
+
async remove(key) {
|
|
68
|
+
return this.vault.remove(key);
|
|
69
|
+
}
|
|
70
|
+
async list(prefix) {
|
|
71
|
+
const all = await this.vault.list(prefix);
|
|
72
|
+
// Filter out manager-internal keys plus the inventory layer's
|
|
73
|
+
// reserved prefixes — `_meta.*` (per-key metadata) and
|
|
74
|
+
// `_routing.config` (global routing rules) are implementation
|
|
75
|
+
// details, not user-visible keys.
|
|
76
|
+
return all.filter((k) => !k.startsWith("_manager.") &&
|
|
77
|
+
!k.startsWith("_meta.") &&
|
|
78
|
+
k !== "_routing.config");
|
|
79
|
+
}
|
|
80
|
+
async detectBackends() {
|
|
81
|
+
return Promise.all([
|
|
82
|
+
Promise.resolve(detectInHouse()),
|
|
83
|
+
detectOnePassword(this.vault),
|
|
84
|
+
detectProtonPass(),
|
|
85
|
+
detectBitwarden(this.vault),
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
async listAllSavedLogins(opts = {}) {
|
|
89
|
+
const requestedDomain = opts.domain
|
|
90
|
+
? opts.domain.trim().toLowerCase()
|
|
91
|
+
: undefined;
|
|
92
|
+
// In-house always queries successfully (or surfaces a real disk error).
|
|
93
|
+
// External backends contribute only when they're signed in. Detection
|
|
94
|
+
// is the gate, but we don't re-detect inline here — we pull the
|
|
95
|
+
// session-token check into each adapter (it throws BackendNotSignedInError
|
|
96
|
+
// when no session is stored), and skip those backends silently.
|
|
97
|
+
const failures = [];
|
|
98
|
+
const inHouseEntries = await this.fetchInHouseEntries(requestedDomain);
|
|
99
|
+
const externalEntries = [];
|
|
100
|
+
const backends = await this.detectBackends();
|
|
101
|
+
const onePasswordReady = backends.find((b) => b.id === "1password")?.signedIn === true;
|
|
102
|
+
const bitwardenReady = backends.find((b) => b.id === "bitwarden")?.signedIn === true;
|
|
103
|
+
if (onePasswordReady) {
|
|
104
|
+
const result = await safeListExternal("1password", () => listOnePasswordLogins(this.vault, this.execFn));
|
|
105
|
+
if (result.ok === true)
|
|
106
|
+
externalEntries.push(...result.entries);
|
|
107
|
+
else
|
|
108
|
+
failures.push({ source: "1password", message: result.message });
|
|
109
|
+
}
|
|
110
|
+
if (bitwardenReady) {
|
|
111
|
+
const result = await safeListExternal("bitwarden", () => listBitwardenLogins(this.vault, this.execFn));
|
|
112
|
+
if (result.ok === true)
|
|
113
|
+
externalEntries.push(...result.entries);
|
|
114
|
+
else
|
|
115
|
+
failures.push({ source: "bitwarden", message: result.message });
|
|
116
|
+
}
|
|
117
|
+
// Domain filter (case-insensitive) applies uniformly. External
|
|
118
|
+
// adapters don't accept domain filters at the CLI layer — bw doesn't
|
|
119
|
+
// expose one and op item list filters by tag/category only — so the
|
|
120
|
+
// cost is "list everything, filter client-side". For a typical user
|
|
121
|
+
// (dozens to low-hundreds of items) this stays under a second.
|
|
122
|
+
const filteredExternal = requestedDomain
|
|
123
|
+
? externalEntries.filter((e) => e.domain !== null && e.domain.toLowerCase() === requestedDomain)
|
|
124
|
+
: externalEntries;
|
|
125
|
+
const externalUnified = filteredExternal
|
|
126
|
+
.map((e) => ({
|
|
127
|
+
source: e.source,
|
|
128
|
+
identifier: e.externalId,
|
|
129
|
+
domain: e.domain,
|
|
130
|
+
username: e.username,
|
|
131
|
+
title: e.title,
|
|
132
|
+
updatedAt: e.updatedAt,
|
|
133
|
+
}))
|
|
134
|
+
.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
135
|
+
// In-house first (sort by domain asc, username asc), then externals
|
|
136
|
+
// by updatedAt desc — matches the spec.
|
|
137
|
+
const sortedInHouse = [...inHouseEntries].sort((a, b) => {
|
|
138
|
+
const dA = (a.domain ?? "").toLowerCase();
|
|
139
|
+
const dB = (b.domain ?? "").toLowerCase();
|
|
140
|
+
if (dA !== dB)
|
|
141
|
+
return dA < dB ? -1 : 1;
|
|
142
|
+
return a.username < b.username ? -1 : a.username > b.username ? 1 : 0;
|
|
143
|
+
});
|
|
144
|
+
return {
|
|
145
|
+
logins: [...sortedInHouse, ...externalUnified],
|
|
146
|
+
failures,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async revealSavedLogin(source, identifier) {
|
|
150
|
+
if (typeof identifier !== "string" || identifier.length === 0) {
|
|
151
|
+
throw new TypeError("revealSavedLogin: identifier required");
|
|
152
|
+
}
|
|
153
|
+
if (source === "in-house") {
|
|
154
|
+
// In-house identifier is "<domain>:<username>". The username can
|
|
155
|
+
// contain `:` (rare in emails, but legitimate as a literal), so we
|
|
156
|
+
// split on the FIRST colon only.
|
|
157
|
+
const colon = identifier.indexOf(":");
|
|
158
|
+
if (colon <= 0) {
|
|
159
|
+
throw new TypeError(`revealSavedLogin: in-house identifier must be "<domain>:<username>", got "${identifier}"`);
|
|
160
|
+
}
|
|
161
|
+
const domain = identifier.slice(0, colon);
|
|
162
|
+
const username = identifier.slice(colon + 1);
|
|
163
|
+
const login = await getSavedLogin(this.vault, domain, username);
|
|
164
|
+
if (!login) {
|
|
165
|
+
throw new Error(`revealSavedLogin: no in-house login for ${domain}:${username}`);
|
|
166
|
+
}
|
|
167
|
+
const reveal = {
|
|
168
|
+
source: "in-house",
|
|
169
|
+
identifier,
|
|
170
|
+
username: login.username,
|
|
171
|
+
password: login.password,
|
|
172
|
+
domain: login.domain,
|
|
173
|
+
...(login.otpSeed ? { totp: login.otpSeed } : {}),
|
|
174
|
+
};
|
|
175
|
+
return reveal;
|
|
176
|
+
}
|
|
177
|
+
if (source === "1password") {
|
|
178
|
+
const out = await revealOnePasswordLogin(this.vault, this.execFn, identifier);
|
|
179
|
+
return mapExternalReveal(out);
|
|
180
|
+
}
|
|
181
|
+
// bitwarden
|
|
182
|
+
const out = await revealBitwardenLogin(this.vault, this.execFn, identifier);
|
|
183
|
+
return mapExternalReveal(out);
|
|
184
|
+
}
|
|
185
|
+
async fetchInHouseEntries(requestedDomain) {
|
|
186
|
+
const summaries = requestedDomain
|
|
187
|
+
? await listSavedLogins(this.vault, requestedDomain)
|
|
188
|
+
: await listSavedLogins(this.vault);
|
|
189
|
+
return summaries.map((s) => ({
|
|
190
|
+
source: "in-house",
|
|
191
|
+
identifier: `${s.domain}:${s.username}`,
|
|
192
|
+
domain: s.domain,
|
|
193
|
+
username: s.username,
|
|
194
|
+
title: s.username,
|
|
195
|
+
updatedAt: s.lastModified,
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
async resolveTargetBackend(key, opts) {
|
|
199
|
+
// Explicit per-call override always wins.
|
|
200
|
+
if (opts.store)
|
|
201
|
+
return opts.store;
|
|
202
|
+
// Non-sensitive values always go in-house — no point routing UI
|
|
203
|
+
// config strings through a password manager. Checked BEFORE the
|
|
204
|
+
// routing map so a stale/misconfigured `routing.ui.theme = "1password"`
|
|
205
|
+
// entry can't accidentally push non-sensitive data into an
|
|
206
|
+
// external store.
|
|
207
|
+
if (!opts.sensitive)
|
|
208
|
+
return "in-house";
|
|
209
|
+
const prefs = await this.getPreferences();
|
|
210
|
+
// Per-key routing override (sensitive case only).
|
|
211
|
+
const routed = prefs.routing?.[key];
|
|
212
|
+
if (routed)
|
|
213
|
+
return routed;
|
|
214
|
+
// Default for sensitive: first enabled backend; in-house if nothing is
|
|
215
|
+
// enabled. External backends currently require explicit references.
|
|
216
|
+
return prefs.enabled[0] ?? "in-house";
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function normalizePreferences(prefs) {
|
|
220
|
+
const validIds = new Set([
|
|
221
|
+
"in-house",
|
|
222
|
+
"1password",
|
|
223
|
+
"protonpass",
|
|
224
|
+
"bitwarden",
|
|
225
|
+
]);
|
|
226
|
+
const enabled = (Array.isArray(prefs.enabled) ? prefs.enabled : []).filter((id) => validIds.has(id));
|
|
227
|
+
if (enabled.length === 0)
|
|
228
|
+
enabled.push("in-house");
|
|
229
|
+
const routing = {};
|
|
230
|
+
if (prefs.routing && typeof prefs.routing === "object") {
|
|
231
|
+
for (const [k, v] of Object.entries(prefs.routing)) {
|
|
232
|
+
if (typeof k === "string" && validIds.has(v)) {
|
|
233
|
+
routing[k] = v;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return { enabled, ...(Object.keys(routing).length > 0 ? { routing } : {}) };
|
|
238
|
+
}
|
|
239
|
+
// ── Detection helpers ──────────────────────────────────────────────
|
|
240
|
+
function detectInHouse() {
|
|
241
|
+
return {
|
|
242
|
+
id: "in-house",
|
|
243
|
+
label: "Eliza (local, encrypted)",
|
|
244
|
+
available: true,
|
|
245
|
+
signedIn: true,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
async function readStoredSession(vault, backend) {
|
|
249
|
+
try {
|
|
250
|
+
const value = await vault.get(`pm.${backend}.session`);
|
|
251
|
+
return value.trim() || null;
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async function detectOnePassword(vault) {
|
|
258
|
+
const present = await isCommandAvailable("op");
|
|
259
|
+
if (!present) {
|
|
260
|
+
return {
|
|
261
|
+
id: "1password",
|
|
262
|
+
label: "1Password",
|
|
263
|
+
available: false,
|
|
264
|
+
detail: "`op` CLI not installed. Get it at https://developer.1password.com/docs/cli",
|
|
265
|
+
authMode: null,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
// 1Password 8's CLI refuses to pick a default account when more than
|
|
269
|
+
// one is registered. `op whoami` with no flags exits 1 ("account is
|
|
270
|
+
// not signed in") even when desktop integration is fully active and
|
|
271
|
+
// every concrete `op vault list --account=<sh>` succeeds. Probe the
|
|
272
|
+
// registered accounts once and pass --account=<sh> to disambiguate.
|
|
273
|
+
const account = await readDefaultOpAccount();
|
|
274
|
+
// Step 1: probe `op whoami --account=<sh>` with no session token. When
|
|
275
|
+
// the user has 1Password 8 desktop app installed and CLI integration
|
|
276
|
+
// enabled, the CLI authenticates via the desktop app and `whoami`
|
|
277
|
+
// returns 0 without any session being passed.
|
|
278
|
+
if (await isOnePasswordDesktopActive(account)) {
|
|
279
|
+
return {
|
|
280
|
+
id: "1password",
|
|
281
|
+
label: "1Password",
|
|
282
|
+
available: true,
|
|
283
|
+
signedIn: true,
|
|
284
|
+
authMode: "desktop-app",
|
|
285
|
+
detail: "Authenticated via 1Password desktop app.",
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
// Step 2: fall back to the stored session token path.
|
|
289
|
+
const session = await readStoredSession(vault, "1password");
|
|
290
|
+
if (!session) {
|
|
291
|
+
return {
|
|
292
|
+
id: "1password",
|
|
293
|
+
label: "1Password",
|
|
294
|
+
available: true,
|
|
295
|
+
signedIn: false,
|
|
296
|
+
authMode: null,
|
|
297
|
+
detail: "`op` is installed but not signed in. Enable 1Password desktop app integration (Settings → Developer → Integrate with 1Password CLI) or use the Sign-in button.",
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
const accountArg = account ? [`--account=${account}`] : [];
|
|
301
|
+
try {
|
|
302
|
+
await exec("op", [...accountArg, "whoami", `--session=${session}`], {
|
|
303
|
+
timeout: 3000,
|
|
304
|
+
});
|
|
305
|
+
return {
|
|
306
|
+
id: "1password",
|
|
307
|
+
label: "1Password",
|
|
308
|
+
available: true,
|
|
309
|
+
signedIn: true,
|
|
310
|
+
authMode: "session-token",
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return {
|
|
315
|
+
id: "1password",
|
|
316
|
+
label: "1Password",
|
|
317
|
+
available: true,
|
|
318
|
+
signedIn: false,
|
|
319
|
+
authMode: null,
|
|
320
|
+
detail: "Stored 1Password session is no longer valid. Sign in again.",
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/** Read the first registered 1Password account shorthand, or null. */
|
|
325
|
+
async function readDefaultOpAccount() {
|
|
326
|
+
try {
|
|
327
|
+
const { stdout } = await exec("op", ["account", "list", "--format=json"], {
|
|
328
|
+
timeout: 3000,
|
|
329
|
+
encoding: "utf8",
|
|
330
|
+
});
|
|
331
|
+
const accounts = JSON.parse(stdout);
|
|
332
|
+
for (const a of accounts) {
|
|
333
|
+
if (typeof a.shorthand === "string" && a.shorthand.length > 0) {
|
|
334
|
+
return a.shorthand;
|
|
335
|
+
}
|
|
336
|
+
if (typeof a.url === "string") {
|
|
337
|
+
const sub = a.url.split(".")[0];
|
|
338
|
+
if (sub)
|
|
339
|
+
return sub;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* True when a real vault query succeeds without a session token — i.e.
|
|
350
|
+
* 1Password desktop app integration is active. `op whoami` is unusable
|
|
351
|
+
* here: even with desktop integration active it exits 1 demanding a
|
|
352
|
+
* session token. A vault list query IS handled by desktop session
|
|
353
|
+
* delegation, so probe with that instead. Requires a known account.
|
|
354
|
+
*/
|
|
355
|
+
async function isOnePasswordDesktopActive(account) {
|
|
356
|
+
if (!account)
|
|
357
|
+
return false;
|
|
358
|
+
try {
|
|
359
|
+
await exec("op", [`--account=${account}`, "vault", "list", "--format=json"], { timeout: 3000 });
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
async function detectProtonPass() {
|
|
367
|
+
const present = await isCommandAvailable("protonpass-cli");
|
|
368
|
+
return {
|
|
369
|
+
id: "protonpass",
|
|
370
|
+
label: "Proton Pass",
|
|
371
|
+
available: present,
|
|
372
|
+
authMode: null,
|
|
373
|
+
detail: present
|
|
374
|
+
? "Detected; reference storage will be wired when the vendor CLI stabilizes."
|
|
375
|
+
: "`protonpass-cli` not installed (vendor CLI is in beta).",
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
async function detectBitwarden(vault) {
|
|
379
|
+
const present = await isCommandAvailable("bw");
|
|
380
|
+
if (!present) {
|
|
381
|
+
return {
|
|
382
|
+
id: "bitwarden",
|
|
383
|
+
label: "Bitwarden",
|
|
384
|
+
available: false,
|
|
385
|
+
detail: "`bw` CLI not installed. https://bitwarden.com/help/cli/",
|
|
386
|
+
authMode: null,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
const session = await readStoredSession(vault, "bitwarden");
|
|
390
|
+
const env = session ? { ...process.env, BW_SESSION: session } : process.env;
|
|
391
|
+
try {
|
|
392
|
+
const { stdout } = await exec("bw", ["status"], {
|
|
393
|
+
timeout: 3000,
|
|
394
|
+
encoding: "utf8",
|
|
395
|
+
env,
|
|
396
|
+
});
|
|
397
|
+
const status = JSON.parse(stdout.trim());
|
|
398
|
+
if (status.status === "unlocked") {
|
|
399
|
+
return {
|
|
400
|
+
id: "bitwarden",
|
|
401
|
+
label: "Bitwarden",
|
|
402
|
+
available: true,
|
|
403
|
+
signedIn: true,
|
|
404
|
+
authMode: session ? "session-token" : null,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
id: "bitwarden",
|
|
409
|
+
label: "Bitwarden",
|
|
410
|
+
available: true,
|
|
411
|
+
signedIn: false,
|
|
412
|
+
authMode: null,
|
|
413
|
+
detail: session
|
|
414
|
+
? "Stored Bitwarden session is no longer valid. Sign in again."
|
|
415
|
+
: status.status === "locked"
|
|
416
|
+
? "`bw` is signed in but locked. Use the Sign-in button."
|
|
417
|
+
: "`bw` is installed but not signed in. Use the Sign-in button.",
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
return {
|
|
422
|
+
id: "bitwarden",
|
|
423
|
+
label: "Bitwarden",
|
|
424
|
+
available: true,
|
|
425
|
+
signedIn: false,
|
|
426
|
+
authMode: null,
|
|
427
|
+
detail: "`bw status` failed; CLI may need an update.",
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function mapExternalReveal(out) {
|
|
432
|
+
return {
|
|
433
|
+
source: out.source,
|
|
434
|
+
identifier: out.externalId,
|
|
435
|
+
username: out.username,
|
|
436
|
+
password: out.password,
|
|
437
|
+
domain: out.domain,
|
|
438
|
+
...(out.totp ? { totp: out.totp } : {}),
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
async function safeListExternal(_source, fn) {
|
|
442
|
+
try {
|
|
443
|
+
const entries = await fn();
|
|
444
|
+
return { ok: true, entries };
|
|
445
|
+
}
|
|
446
|
+
catch (err) {
|
|
447
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
448
|
+
return { ok: false, message };
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
async function isCommandAvailable(cmd) {
|
|
452
|
+
try {
|
|
453
|
+
if (process.platform === "win32") {
|
|
454
|
+
await exec("where.exe", [cmd], { timeout: 3000 });
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
// Use `which` directly — argv array, no shell interpolation.
|
|
458
|
+
await exec("which", [cmd], { timeout: 3000 });
|
|
459
|
+
}
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"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"}
|