unotoken 0.1.0

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.
Files changed (122) hide show
  1. package/README.md +360 -0
  2. package/dist/cli.d.ts +17 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +1207 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/client.d.ts +15 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +15 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/db.d.ts +52 -0
  11. package/dist/db.d.ts.map +1 -0
  12. package/dist/db.js +97 -0
  13. package/dist/db.js.map +1 -0
  14. package/dist/dotenv.d.ts +69 -0
  15. package/dist/dotenv.d.ts.map +1 -0
  16. package/dist/dotenv.js +115 -0
  17. package/dist/dotenv.js.map +1 -0
  18. package/dist/env-mapper.d.ts +55 -0
  19. package/dist/env-mapper.d.ts.map +1 -0
  20. package/dist/env-mapper.js +97 -0
  21. package/dist/env-mapper.js.map +1 -0
  22. package/dist/exec.d.ts +80 -0
  23. package/dist/exec.d.ts.map +1 -0
  24. package/dist/exec.js +214 -0
  25. package/dist/exec.js.map +1 -0
  26. package/dist/index.d.ts +12 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +43 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/oauth/commands.d.ts +151 -0
  31. package/dist/oauth/commands.d.ts.map +1 -0
  32. package/dist/oauth/commands.js +322 -0
  33. package/dist/oauth/commands.js.map +1 -0
  34. package/dist/oauth/config.d.ts +84 -0
  35. package/dist/oauth/config.d.ts.map +1 -0
  36. package/dist/oauth/config.js +156 -0
  37. package/dist/oauth/config.js.map +1 -0
  38. package/dist/oauth/crypto-helpers.d.ts +44 -0
  39. package/dist/oauth/crypto-helpers.d.ts.map +1 -0
  40. package/dist/oauth/crypto-helpers.js +94 -0
  41. package/dist/oauth/crypto-helpers.js.map +1 -0
  42. package/dist/oauth/device-secret.d.ts +57 -0
  43. package/dist/oauth/device-secret.d.ts.map +1 -0
  44. package/dist/oauth/device-secret.js +106 -0
  45. package/dist/oauth/device-secret.js.map +1 -0
  46. package/dist/oauth/flow.d.ts +112 -0
  47. package/dist/oauth/flow.d.ts.map +1 -0
  48. package/dist/oauth/flow.js +255 -0
  49. package/dist/oauth/flow.js.map +1 -0
  50. package/dist/oauth/index.d.ts +18 -0
  51. package/dist/oauth/index.d.ts.map +1 -0
  52. package/dist/oauth/index.js +24 -0
  53. package/dist/oauth/index.js.map +1 -0
  54. package/dist/oauth/key-wrap.d.ts +146 -0
  55. package/dist/oauth/key-wrap.d.ts.map +1 -0
  56. package/dist/oauth/key-wrap.js +275 -0
  57. package/dist/oauth/key-wrap.js.map +1 -0
  58. package/dist/oauth/pkce.d.ts +29 -0
  59. package/dist/oauth/pkce.d.ts.map +1 -0
  60. package/dist/oauth/pkce.js +34 -0
  61. package/dist/oauth/pkce.js.map +1 -0
  62. package/dist/oauth/provider.d.ts +79 -0
  63. package/dist/oauth/provider.d.ts.map +1 -0
  64. package/dist/oauth/provider.js +10 -0
  65. package/dist/oauth/provider.js.map +1 -0
  66. package/dist/oauth/providers/github.d.ts +75 -0
  67. package/dist/oauth/providers/github.d.ts.map +1 -0
  68. package/dist/oauth/providers/github.js +119 -0
  69. package/dist/oauth/providers/github.js.map +1 -0
  70. package/dist/oauth/providers/google.d.ts +115 -0
  71. package/dist/oauth/providers/google.d.ts.map +1 -0
  72. package/dist/oauth/providers/google.js +285 -0
  73. package/dist/oauth/providers/google.js.map +1 -0
  74. package/dist/sdk.d.ts +8 -0
  75. package/dist/sdk.d.ts.map +1 -0
  76. package/dist/sdk.js +8 -0
  77. package/dist/sdk.js.map +1 -0
  78. package/dist/server.d.ts +33 -0
  79. package/dist/server.d.ts.map +1 -0
  80. package/dist/server.js +287 -0
  81. package/dist/server.js.map +1 -0
  82. package/dist/signatures/approval-codes.d.ts +192 -0
  83. package/dist/signatures/approval-codes.d.ts.map +1 -0
  84. package/dist/signatures/approval-codes.js +407 -0
  85. package/dist/signatures/approval-codes.js.map +1 -0
  86. package/dist/signatures/commands.d.ts +108 -0
  87. package/dist/signatures/commands.d.ts.map +1 -0
  88. package/dist/signatures/commands.js +270 -0
  89. package/dist/signatures/commands.js.map +1 -0
  90. package/dist/signatures/devices.d.ts +165 -0
  91. package/dist/signatures/devices.d.ts.map +1 -0
  92. package/dist/signatures/devices.js +344 -0
  93. package/dist/signatures/devices.js.map +1 -0
  94. package/dist/signatures/email-config.d.ts +102 -0
  95. package/dist/signatures/email-config.d.ts.map +1 -0
  96. package/dist/signatures/email-config.js +188 -0
  97. package/dist/signatures/email-config.js.map +1 -0
  98. package/dist/signatures/email.d.ts +106 -0
  99. package/dist/signatures/email.d.ts.map +1 -0
  100. package/dist/signatures/email.js +180 -0
  101. package/dist/signatures/email.js.map +1 -0
  102. package/dist/signatures/fingerprint.d.ts +70 -0
  103. package/dist/signatures/fingerprint.d.ts.map +1 -0
  104. package/dist/signatures/fingerprint.js +123 -0
  105. package/dist/signatures/fingerprint.js.map +1 -0
  106. package/dist/signatures/guard.d.ts +118 -0
  107. package/dist/signatures/guard.d.ts.map +1 -0
  108. package/dist/signatures/guard.js +310 -0
  109. package/dist/signatures/guard.js.map +1 -0
  110. package/dist/signatures/resend.d.ts +84 -0
  111. package/dist/signatures/resend.d.ts.map +1 -0
  112. package/dist/signatures/resend.js +248 -0
  113. package/dist/signatures/resend.js.map +1 -0
  114. package/dist/token-requests.d.ts +80 -0
  115. package/dist/token-requests.d.ts.map +1 -0
  116. package/dist/token-requests.js +201 -0
  117. package/dist/token-requests.js.map +1 -0
  118. package/dist/tokens.d.ts +80 -0
  119. package/dist/tokens.d.ts.map +1 -0
  120. package/dist/tokens.js +150 -0
  121. package/dist/tokens.js.map +1 -0
  122. package/package.json +62 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * env-mapper — Convert vault secret paths to environment variable names.
3
+ *
4
+ * Used by `exec` and `dotenv` commands to inject vault secrets as env vars.
5
+ *
6
+ * Mapping rules:
7
+ * 1. Strip the prefix from the path (e.g., "levelfit/" from "levelfit/stripe/secret/key")
8
+ * 2. Replace slashes with underscores
9
+ * 3. Uppercase the result
10
+ *
11
+ * Example: prefix="levelfit/", path="levelfit/stripe/secret/key" → "STRIPE_SECRET_KEY"
12
+ */
13
+ /**
14
+ * Strip a prefix from a vault secret path.
15
+ *
16
+ * @param secretPath - Full secret path (e.g., "levelfit/stripe/secret/key")
17
+ * @param prefix - Prefix to strip (e.g., "levelfit/")
18
+ * @returns Remaining path after prefix removal
19
+ */
20
+ export function stripPrefix(secretPath, prefix) {
21
+ if (!prefix)
22
+ return secretPath;
23
+ // Normalize: ensure prefix ends with /
24
+ const normalizedPrefix = prefix.endsWith('/') ? prefix : prefix + '/';
25
+ if (secretPath.startsWith(normalizedPrefix)) {
26
+ return secretPath.slice(normalizedPrefix.length);
27
+ }
28
+ return secretPath;
29
+ }
30
+ /**
31
+ * Convert a vault secret path (after prefix stripping) to an env var name.
32
+ *
33
+ * @param pathAfterPrefix - Path with prefix already stripped (e.g., "stripe/secret/key")
34
+ * @returns Environment variable name (e.g., "STRIPE_SECRET_KEY")
35
+ */
36
+ export function pathToEnvVar(pathAfterPrefix) {
37
+ return pathAfterPrefix
38
+ .replace(/\//g, '_')
39
+ .toUpperCase();
40
+ }
41
+ /**
42
+ * Convert a full vault secret path to an env var name, stripping the given prefix.
43
+ *
44
+ * @param secretPath - Full secret path (e.g., "levelfit/stripe/secret/key")
45
+ * @param prefix - Prefix to strip (e.g., "levelfit/")
46
+ * @returns Environment variable name (e.g., "STRIPE_SECRET_KEY")
47
+ */
48
+ export function secretPathToEnvVar(secretPath, prefix) {
49
+ const stripped = stripPrefix(secretPath, prefix);
50
+ return pathToEnvVar(stripped);
51
+ }
52
+ /**
53
+ * Build an env var map from vault secrets.
54
+ *
55
+ * @param secrets - Array of { path, value } from the vault
56
+ * @param prefix - Prefix to strip when converting to env var names
57
+ * @returns Map of env var name to value
58
+ */
59
+ export function buildEnvMap(secrets, prefix) {
60
+ const env = {};
61
+ for (const secret of secrets) {
62
+ const envVar = secretPathToEnvVar(secret.path, prefix);
63
+ env[envVar] = secret.value;
64
+ }
65
+ return env;
66
+ }
67
+ /**
68
+ * Parse a .env file into key-value pairs.
69
+ * Handles: KEY=VALUE, quoted values, comments, blank lines.
70
+ *
71
+ * @param content - Raw .env file content
72
+ * @returns Record of key-value pairs
73
+ */
74
+ export function parseEnvFile(content) {
75
+ const env = {};
76
+ for (const line of content.split('\n')) {
77
+ const trimmed = line.trim();
78
+ // Skip empty lines and comments
79
+ if (!trimmed || trimmed.startsWith('#'))
80
+ continue;
81
+ const eqIndex = trimmed.indexOf('=');
82
+ if (eqIndex === -1)
83
+ continue;
84
+ const key = trimmed.slice(0, eqIndex).trim();
85
+ let value = trimmed.slice(eqIndex + 1).trim();
86
+ // Remove surrounding quotes
87
+ if ((value.startsWith('"') && value.endsWith('"')) ||
88
+ (value.startsWith("'") && value.endsWith("'"))) {
89
+ value = value.slice(1, -1);
90
+ }
91
+ if (key) {
92
+ env[key] = value;
93
+ }
94
+ }
95
+ return env;
96
+ }
97
+ //# sourceMappingURL=env-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-mapper.js","sourceRoot":"","sources":["../src/env-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB,EAAE,MAAc;IAC5D,IAAI,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC;IAE/B,uCAAuC;IACvC,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;IAEtE,IAAI,UAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC5C,OAAO,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,eAAuB;IAClD,OAAO,eAAe;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,MAAc;IACnE,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,OAA+C,EAC/C,MAAc;IAEd,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvD,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,gCAAgC;QAChC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE9C,4BAA4B;QAC5B,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;YACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,GAAG,EAAE,CAAC;YACR,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/exec.d.ts ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * exec — Spawn a child process with vault secrets injected as env vars.
3
+ *
4
+ * Usage: unotoken exec --prefix levelfit/ -- npm run dev
5
+ *
6
+ * Fetches all secrets under the given prefix from the vault, converts
7
+ * them to env vars (prefix stripped, slashes → underscores, uppercased),
8
+ * and spawns the child process with those vars merged into the environment.
9
+ */
10
+ export interface ExecOptions {
11
+ /** Vault prefix to fetch secrets from (e.g., "levelfit/") */
12
+ prefix: string;
13
+ /** Command and arguments to run */
14
+ command: string[];
15
+ /** Bearer token for vault authentication */
16
+ token: string;
17
+ /** Vault server host (default: "127.0.0.1") */
18
+ host?: string;
19
+ /** Vault server port */
20
+ port: number;
21
+ /** If true, vault values override existing env vars with matching keys (default: true) */
22
+ force?: boolean;
23
+ /** Optional supplementary .env file path */
24
+ envFile?: string;
25
+ /** Whether to use HTTPS (default: false for local) */
26
+ insecure?: boolean;
27
+ }
28
+ export interface VaultSecret {
29
+ path: string;
30
+ value: string;
31
+ }
32
+ /**
33
+ * Fetch all secrets under a prefix from the vault.
34
+ *
35
+ * @param opts - Connection options
36
+ * @returns Array of { path, value } for each secret
37
+ */
38
+ export declare function fetchSecretsForPrefix(opts: {
39
+ prefix: string;
40
+ token: string;
41
+ host: string;
42
+ port: number;
43
+ insecure?: boolean;
44
+ }): Promise<VaultSecret[]>;
45
+ /**
46
+ * Build the environment for the child process.
47
+ *
48
+ * Merges: process.env + envFile (if any) + vault secrets.
49
+ * By default, vault secrets take precedence over existing env vars.
50
+ * Use force=false to skip vault vars that already exist in the environment.
51
+ */
52
+ export declare function buildChildEnv(opts: {
53
+ secrets: VaultSecret[];
54
+ prefix: string;
55
+ force?: boolean;
56
+ envFile?: string;
57
+ baseEnv?: Record<string, string | undefined>;
58
+ }): Record<string, string>;
59
+ /**
60
+ * Execute a command with vault secrets injected as env vars.
61
+ *
62
+ * @returns Exit code of the child process
63
+ */
64
+ export declare function execWithVaultSecrets(opts: ExecOptions): Promise<number>;
65
+ /**
66
+ * Resolve the vault token from options, env var, or token file.
67
+ *
68
+ * Priority: explicit token > UNOTOKEN_TOKEN env var > ~/.yokotoken/token
69
+ */
70
+ export declare function resolveToken(explicitToken?: string): Promise<string>;
71
+ /**
72
+ * Resolve the vault port from options, env var, or port file.
73
+ *
74
+ * Priority: explicit vault-url > UNOTOKEN_URL env var > port file
75
+ */
76
+ export declare function resolveVaultConnection(vaultUrl?: string): Promise<{
77
+ host: string;
78
+ port: number;
79
+ }>;
80
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IAEf,mCAAmC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IAEd,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IAEb,0FAA0F;IAC1F,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAwCzB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC9C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCzB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAgD7E;AAgBD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAsCzC"}
package/dist/exec.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * exec — Spawn a child process with vault secrets injected as env vars.
3
+ *
4
+ * Usage: unotoken exec --prefix levelfit/ -- npm run dev
5
+ *
6
+ * Fetches all secrets under the given prefix from the vault, converts
7
+ * them to env vars (prefix stripped, slashes → underscores, uppercased),
8
+ * and spawns the child process with those vars merged into the environment.
9
+ */
10
+ import { spawn } from 'node:child_process';
11
+ import fs from 'node:fs';
12
+ import { buildEnvMap, parseEnvFile } from './env-mapper.js';
13
+ /**
14
+ * Fetch all secrets under a prefix from the vault.
15
+ *
16
+ * @param opts - Connection options
17
+ * @returns Array of { path, value } for each secret
18
+ */
19
+ export async function fetchSecretsForPrefix(opts) {
20
+ const { vaultRequest } = await import('yokotoken');
21
+ const config = {
22
+ port: opts.port,
23
+ host: opts.host,
24
+ token: opts.token,
25
+ insecure: opts.insecure !== false, // default true for local
26
+ };
27
+ // List secrets under the prefix
28
+ const listRes = await vaultRequest(config, 'GET', `/v1/secrets?prefix=${encodeURIComponent(opts.prefix)}`);
29
+ if (listRes.statusCode !== 200) {
30
+ const body = listRes.body;
31
+ throw new Error(body.error || `Failed to list secrets (HTTP ${listRes.statusCode})`);
32
+ }
33
+ const entries = listRes.body.entries || [];
34
+ // Fetch each secret's value
35
+ const secrets = [];
36
+ for (const entry of entries) {
37
+ const getRes = await vaultRequest(config, 'GET', `/v1/secrets/${encodeURIComponent(entry.path)}`);
38
+ if (getRes.statusCode === 200) {
39
+ const body = getRes.body;
40
+ secrets.push({ path: entry.path, value: body.value });
41
+ }
42
+ }
43
+ return secrets;
44
+ }
45
+ /**
46
+ * Build the environment for the child process.
47
+ *
48
+ * Merges: process.env + envFile (if any) + vault secrets.
49
+ * By default, vault secrets take precedence over existing env vars.
50
+ * Use force=false to skip vault vars that already exist in the environment.
51
+ */
52
+ export function buildChildEnv(opts) {
53
+ const base = opts.baseEnv ?? process.env;
54
+ const force = opts.force !== false; // default: vault values take precedence
55
+ // Start with current environment
56
+ const env = {};
57
+ for (const [key, value] of Object.entries(base)) {
58
+ if (value !== undefined) {
59
+ env[key] = value;
60
+ }
61
+ }
62
+ // Layer 2: supplementary .env file (if provided)
63
+ if (opts.envFile) {
64
+ const content = fs.readFileSync(opts.envFile, 'utf-8');
65
+ const envFileVars = parseEnvFile(content);
66
+ Object.assign(env, envFileVars);
67
+ }
68
+ // Layer 3: vault secrets
69
+ const vaultEnv = buildEnvMap(opts.secrets, opts.prefix);
70
+ if (force) {
71
+ // Vault values override everything
72
+ Object.assign(env, vaultEnv);
73
+ }
74
+ else {
75
+ // Only set vault values that don't already exist
76
+ for (const [key, value] of Object.entries(vaultEnv)) {
77
+ if (!(key in env)) {
78
+ env[key] = value;
79
+ }
80
+ }
81
+ }
82
+ return env;
83
+ }
84
+ /**
85
+ * Execute a command with vault secrets injected as env vars.
86
+ *
87
+ * @returns Exit code of the child process
88
+ */
89
+ export async function execWithVaultSecrets(opts) {
90
+ const host = opts.host ?? '127.0.0.1';
91
+ const prefix = opts.prefix;
92
+ // Fetch secrets from vault
93
+ const secrets = await fetchSecretsForPrefix({
94
+ prefix,
95
+ token: opts.token,
96
+ host,
97
+ port: opts.port,
98
+ insecure: opts.insecure,
99
+ });
100
+ // Build child environment
101
+ const childEnv = buildChildEnv({
102
+ secrets,
103
+ prefix,
104
+ force: opts.force,
105
+ envFile: opts.envFile,
106
+ });
107
+ // Spawn child process
108
+ const [cmd, ...args] = opts.command;
109
+ if (!cmd) {
110
+ throw new Error('No command specified');
111
+ }
112
+ return new Promise((resolve, reject) => {
113
+ const child = spawn(cmd, args, {
114
+ stdio: 'inherit',
115
+ env: childEnv,
116
+ shell: true,
117
+ });
118
+ child.on('error', (err) => {
119
+ reject(new Error(`Failed to start command '${cmd}': ${err.message}`));
120
+ });
121
+ child.on('exit', (code, signal) => {
122
+ if (signal) {
123
+ // Process was killed by a signal
124
+ resolve(128 + (signalToNumber(signal) || 1));
125
+ }
126
+ else {
127
+ resolve(code ?? 1);
128
+ }
129
+ });
130
+ });
131
+ }
132
+ /**
133
+ * Convert a signal name to its numeric value.
134
+ */
135
+ function signalToNumber(signal) {
136
+ const signals = {
137
+ SIGHUP: 1,
138
+ SIGINT: 2,
139
+ SIGQUIT: 3,
140
+ SIGTERM: 15,
141
+ SIGKILL: 9,
142
+ };
143
+ return signals[signal] || 0;
144
+ }
145
+ /**
146
+ * Resolve the vault token from options, env var, or token file.
147
+ *
148
+ * Priority: explicit token > UNOTOKEN_TOKEN env var > ~/.yokotoken/token
149
+ */
150
+ export async function resolveToken(explicitToken) {
151
+ // 1. Explicit token from --token flag
152
+ if (explicitToken)
153
+ return explicitToken;
154
+ // 2. UNOTOKEN_TOKEN environment variable
155
+ const envToken = process.env['UNOTOKEN_TOKEN'];
156
+ if (envToken)
157
+ return envToken;
158
+ // 3. Token file (~/.yokotoken/token)
159
+ try {
160
+ const { readTokenFile, getDefaultTokenFile } = await import('yokotoken');
161
+ const tokenFile = getDefaultTokenFile();
162
+ const fileToken = readTokenFile(tokenFile);
163
+ if (fileToken)
164
+ return fileToken;
165
+ }
166
+ catch {
167
+ // Token file not found or unreadable
168
+ }
169
+ throw new Error('No authentication token found. Provide one via:\n' +
170
+ ' --token <token>\n' +
171
+ ' UNOTOKEN_TOKEN environment variable\n' +
172
+ ' ~/.yokotoken/token file (created by vault server)');
173
+ }
174
+ /**
175
+ * Resolve the vault port from options, env var, or port file.
176
+ *
177
+ * Priority: explicit vault-url > UNOTOKEN_URL env var > port file
178
+ */
179
+ export async function resolveVaultConnection(vaultUrl) {
180
+ // 1. Explicit --vault-url
181
+ if (vaultUrl) {
182
+ const url = new URL(vaultUrl);
183
+ return {
184
+ host: url.hostname,
185
+ port: parseInt(url.port, 10) || (url.protocol === 'https:' ? 443 : 80),
186
+ };
187
+ }
188
+ // 2. UNOTOKEN_URL environment variable
189
+ const envUrl = process.env['UNOTOKEN_URL'];
190
+ if (envUrl) {
191
+ const url = new URL(envUrl);
192
+ return {
193
+ host: url.hostname,
194
+ port: parseInt(url.port, 10) || (url.protocol === 'https:' ? 443 : 80),
195
+ };
196
+ }
197
+ // 3. Port file (local vault)
198
+ try {
199
+ const { readServerPort, getDefaultPortFile } = await import('yokotoken');
200
+ const portFile = getDefaultPortFile();
201
+ const port = readServerPort(portFile);
202
+ if (port) {
203
+ return { host: '127.0.0.1', port };
204
+ }
205
+ }
206
+ catch {
207
+ // Port file not found
208
+ }
209
+ throw new Error('Cannot reach vault. Ensure the vault server is running, or provide:\n' +
210
+ ' --vault-url <url>\n' +
211
+ ' UNOTOKEN_URL environment variable\n' +
212
+ ' Start local vault with: unotoken server');
213
+ }
214
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * unotoken — yokotoken + cloud features.
3
+ *
4
+ * Re-exports the entire yokotoken public API so that `unotoken` can be used
5
+ * as a drop-in replacement. Cloud-specific exports (OAuth, team vaults,
6
+ * key escrow) are added as additional named exports.
7
+ */
8
+ export { VaultEngine, type SecretEntry, type SecretMetadata, type SecretListEntry, type VaultStatus, createVaultServer, getDefaultVaultPath, getDefaultPidFile, getDefaultPortFile, getVaultDir, isServerRunning, readServerPort, DEFAULT_PORT, DEFAULT_IDLE_TIMEOUT_MS, type ServerConfig, vaultRequest, type ClientConfig, type ClientResponse, readPassphrase, readAndConfirmPassphrase, generateToken, getDefaultTokenFile, writeTokenFile, readTokenFile, validateBearerToken, RateLimiter, DEFAULT_RATE_LIMIT, type RateLimitConfig, ensureCerts, generateSelfSignedCert, getDefaultCertPaths, certsExist, type TlsCertPaths, type TlsCertData, TokenManager, generateAccessToken, hashToken, parseTTL, type TokenCreateOptions, type TokenCreateResult, type TokenMetadata, type TokenValidationResult, getSecret, storeSecret, listSecrets, VaultSdkError, type VaultSdkConfig, startDaemon, stopDaemon, restartDaemon, rotateLogIfNeeded, getDefaultLogFile, MAX_LOG_SIZE, type DaemonStartOptions, type DaemonStartResult, type DaemonStopResult, AuditLogger, readAuditLog, tailAuditLog, getDefaultAuditLogPath, type AuditOperation, type AuditEntry, type AuditFilterOptions, createBackup, restoreBackup, exportEnv, importEnv, parseEnvFile, pathToEnvName, envNameToPath, detectImportDuplicates, BACKUP_MAGIC, BACKUP_VERSION, BACKUP_HEADER_SIZE, type BackupResult, type RestoreResult, type ExportResult, type ImportResult, type ImportConflictStrategy, type ImportDuplicate, type EnvEntry, IdentityDatabase, getDefaultIdentityDbPath, type Identity, type IdentityType, type Org, type Project, type OrgMember, type ProjectMember, type MemberRole, type IdentityCreateResult, NetworkVaultClient, NetworkClientError, type NetworkClientConfig, type NetworkClientResponse, readConfig, writeConfig, setConfigField, getConfigField, deleteConfigField, resolveFieldName, formatConfigForDisplay, getDefaultConfigPath, getValidFields, type VaultConfig, type VaultConfigField, } from 'yokotoken';
9
+ export { matchesPrefix, checkTokenScope, filterByTokenScope, storeTokenScopes, revokeTokenScopes, formatScopes, buildScopesByName, intersectPrefixWithScopes, type ScopeCheckResult, } from './tokens.js';
10
+ export { loadTokenScopes, saveTokenScopes, setTokenScopes, getTokenScopes, removeTokenScopesByName, listTokenScopes, getDefaultScopesPath, type TokenScopeEntry, type TokenScopeStore, } from './db.js';
11
+ export { createScopedVaultServer, type ScopedServerConfig, } from './server.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAEL,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,WAAW,EAGhB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,uBAAuB,EACvB,KAAK,YAAY,EAGjB,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,cAAc,EAGnB,cAAc,EACd,wBAAwB,EAGxB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,KAAK,eAAe,EAGpB,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,EACV,KAAK,YAAY,EACjB,KAAK,WAAW,EAGhB,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAG1B,SAAS,EACT,WAAW,EACX,WAAW,EACX,aAAa,EACb,KAAK,cAAc,EAGnB,WAAW,EACX,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EAGrB,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,kBAAkB,EAGvB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,QAAQ,EAGb,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,oBAAoB,EAGzB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAG1B,UAAU,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AAKnB,OAAO,EACL,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,uBAAuB,EACvB,eAAe,EACf,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * unotoken — yokotoken + cloud features.
3
+ *
4
+ * Re-exports the entire yokotoken public API so that `unotoken` can be used
5
+ * as a drop-in replacement. Cloud-specific exports (OAuth, team vaults,
6
+ * key escrow) are added as additional named exports.
7
+ */
8
+ // Re-export everything from yokotoken core
9
+ export {
10
+ // Vault engine
11
+ VaultEngine,
12
+ // Server
13
+ createVaultServer, getDefaultVaultPath, getDefaultPidFile, getDefaultPortFile, getVaultDir, isServerRunning, readServerPort, DEFAULT_PORT, DEFAULT_IDLE_TIMEOUT_MS,
14
+ // Client
15
+ vaultRequest,
16
+ // Passphrase
17
+ readPassphrase, readAndConfirmPassphrase,
18
+ // Auth
19
+ generateToken, getDefaultTokenFile, writeTokenFile, readTokenFile, validateBearerToken, RateLimiter, DEFAULT_RATE_LIMIT,
20
+ // TLS
21
+ ensureCerts, generateSelfSignedCert, getDefaultCertPaths, certsExist,
22
+ // Tokens
23
+ TokenManager, generateAccessToken, hashToken, parseTTL,
24
+ // SDK
25
+ getSecret, storeSecret, listSecrets, VaultSdkError,
26
+ // Daemon
27
+ startDaemon, stopDaemon, restartDaemon, rotateLogIfNeeded, getDefaultLogFile, MAX_LOG_SIZE,
28
+ // Audit
29
+ AuditLogger, readAuditLog, tailAuditLog, getDefaultAuditLogPath,
30
+ // Backup
31
+ createBackup, restoreBackup, exportEnv, importEnv, parseEnvFile, pathToEnvName, envNameToPath, detectImportDuplicates, BACKUP_MAGIC, BACKUP_VERSION, BACKUP_HEADER_SIZE,
32
+ // Identity
33
+ IdentityDatabase, getDefaultIdentityDbPath,
34
+ // Network Client
35
+ NetworkVaultClient, NetworkClientError,
36
+ // Config
37
+ readConfig, writeConfig, setConfigField, getConfigField, deleteConfigField, resolveFieldName, formatConfigForDisplay, getDefaultConfigPath, getValidFields, } from 'yokotoken';
38
+ // ─── unotoken-specific exports ──────────────────────────────────────
39
+ // Scoped tokens (US-001)
40
+ export { matchesPrefix, checkTokenScope, filterByTokenScope, storeTokenScopes, revokeTokenScopes, formatScopes, buildScopesByName, intersectPrefixWithScopes, } from './tokens.js';
41
+ export { loadTokenScopes, saveTokenScopes, setTokenScopes, getTokenScopes, removeTokenScopesByName, listTokenScopes, getDefaultScopesPath, } from './db.js';
42
+ export { createScopedVaultServer, } from './server.js';
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,2CAA2C;AAC3C,OAAO;AACL,eAAe;AACf,WAAW;AAMX,SAAS;AACT,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,uBAAuB;AAGvB,SAAS;AACT,YAAY;AAIZ,aAAa;AACb,cAAc,EACd,wBAAwB;AAExB,OAAO;AACP,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,kBAAkB;AAGlB,MAAM;AACN,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,UAAU;AAIV,SAAS;AACT,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,QAAQ;AAMR,MAAM;AACN,SAAS,EACT,WAAW,EACX,WAAW,EACX,aAAa;AAGb,SAAS;AACT,WAAW,EACX,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,YAAY;AAKZ,QAAQ;AACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,sBAAsB;AAKtB,SAAS;AACT,YAAY,EACZ,aAAa,EACb,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,kBAAkB;AASlB,WAAW;AACX,gBAAgB,EAChB,wBAAwB;AAUxB,iBAAiB;AACjB,kBAAkB,EAClB,kBAAkB;AAIlB,SAAS;AACT,UAAU,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,GAGf,MAAM,WAAW,CAAC;AAEnB,uEAAuE;AAEvE,yBAAyB;AACzB,OAAO,EACL,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,yBAAyB,GAE1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,uBAAuB,EACvB,eAAe,EACf,oBAAoB,GAGrB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,uBAAuB,GAExB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * OAuth CLI command handlers for unotoken.
3
+ *
4
+ * Implements:
5
+ * - `auth link <provider>` — Link an OAuth identity for passwordless unlock
6
+ * - `unlock --oauth` — Unlock the vault using a linked OAuth identity
7
+ *
8
+ * These commands bridge the OAuth flow engine, key wrapping, and yokotoken's
9
+ * vault engine to provide a passwordless unlock experience.
10
+ *
11
+ * @module
12
+ */
13
+ import { type OAuthFlowConfig } from './flow.js';
14
+ import type { OAuthProvider } from './provider.js';
15
+ export type ProviderName = 'google' | 'github';
16
+ export interface AuthLinkOptions {
17
+ /** Passphrase to derive the master key (vault must be initialized) */
18
+ passphrase: string;
19
+ /** Path to the vault database (default: ~/.hq-vault/vault.db) */
20
+ vaultPath?: string;
21
+ /** Device directory for device.key storage (default: ~/.yokotoken) */
22
+ deviceDir?: string;
23
+ /** OAuth flow configuration overrides (for testing) */
24
+ flowConfig?: OAuthFlowConfig;
25
+ /** Custom Google provider options */
26
+ googleOptions?: {
27
+ clientId?: string;
28
+ fetch?: typeof globalThis.fetch;
29
+ };
30
+ /** Custom GitHub provider options */
31
+ githubOptions?: {
32
+ clientId?: string;
33
+ clientSecret?: string;
34
+ fetch?: typeof globalThis.fetch;
35
+ };
36
+ }
37
+ export interface AuthLinkResult {
38
+ provider: ProviderName;
39
+ email?: string;
40
+ name?: string;
41
+ subjectId: string;
42
+ }
43
+ export interface UnlockOAuthOptions {
44
+ /** Specific provider to use (if omitted and multiple linked, must choose) */
45
+ provider?: ProviderName;
46
+ /** Path to the vault database (default: ~/.hq-vault/vault.db) */
47
+ vaultPath?: string;
48
+ /** Device directory for device.key storage (default: ~/.yokotoken) */
49
+ deviceDir?: string;
50
+ /** OAuth flow configuration overrides (for testing) */
51
+ flowConfig?: OAuthFlowConfig;
52
+ /** Custom Google provider options */
53
+ googleOptions?: {
54
+ clientId?: string;
55
+ fetch?: typeof globalThis.fetch;
56
+ };
57
+ /** Custom GitHub provider options */
58
+ githubOptions?: {
59
+ clientId?: string;
60
+ clientSecret?: string;
61
+ fetch?: typeof globalThis.fetch;
62
+ };
63
+ /** If true, attempt to notify the running server (default: true) */
64
+ sendToServer?: boolean;
65
+ }
66
+ export interface UnlockOAuthResult {
67
+ provider: ProviderName;
68
+ email?: string;
69
+ name?: string;
70
+ /** Whether the vault server was notified */
71
+ serverNotified: boolean;
72
+ }
73
+ export interface LinkedProvider {
74
+ provider: string;
75
+ subjectId: string;
76
+ createdAt: string;
77
+ lastUsedAt: string;
78
+ }
79
+ /**
80
+ * Validate that a provider name is supported.
81
+ */
82
+ export declare function isValidProvider(name: string): name is ProviderName;
83
+ /**
84
+ * Create an OAuthProvider instance for the given provider name.
85
+ */
86
+ export declare function resolveProvider(name: ProviderName, options?: AuthLinkOptions | UnlockOAuthOptions): OAuthProvider;
87
+ /**
88
+ * Link an OAuth identity to the vault for passwordless unlock.
89
+ *
90
+ * Flow:
91
+ * 1. Open vault database
92
+ * 2. Derive master key from passphrase (verifies passphrase is correct)
93
+ * 3. Run OAuth browser flow to authenticate the user
94
+ * 4. Wrap (encrypt) the master key with the OAuth identity
95
+ * 5. Store the wrapped key in the oauth_links table
96
+ *
97
+ * The vault must be initialized (have a passphrase set). The user provides
98
+ * their passphrase to prove ownership before linking.
99
+ *
100
+ * @param providerName - OAuth provider to link ('google' or 'github')
101
+ * @param options - Configuration options
102
+ * @returns Link result with provider info and user identity
103
+ */
104
+ export declare function authLink(providerName: ProviderName, options: AuthLinkOptions): Promise<AuthLinkResult>;
105
+ /**
106
+ * Unlock the vault using a linked OAuth identity.
107
+ *
108
+ * Flow:
109
+ * 1. Open vault database, list linked providers
110
+ * 2. If provider not specified and multiple linked, throw (caller must choose)
111
+ * 3. Run OAuth browser flow to authenticate the user
112
+ * 4. Unwrap (decrypt) the master key using the OAuth identity
113
+ * 5. Verify the unwrapped key against the vault's verification entry
114
+ * 6. Optionally notify the running vault server
115
+ *
116
+ * @param options - Configuration options
117
+ * @returns Unlock result with provider info
118
+ */
119
+ export declare function unlockWithOAuth(options?: UnlockOAuthOptions): Promise<UnlockOAuthResult>;
120
+ /**
121
+ * List all linked OAuth providers for the vault.
122
+ *
123
+ * Does NOT require the vault to be unlocked — reads the oauth_links table.
124
+ */
125
+ export declare function listLinkedProviders(vaultPath?: string): Promise<LinkedProvider[]>;
126
+ export interface UnlinkResult {
127
+ provider: string;
128
+ /** Whether this was the last linked provider (user now has passphrase only) */
129
+ wasLastProvider: boolean;
130
+ }
131
+ /**
132
+ * Remove an OAuth link for a specific provider.
133
+ *
134
+ * Does NOT require the vault to be unlocked — modifies the oauth_links table directly.
135
+ *
136
+ * @param providerName - OAuth provider to unlink ('google' or 'github')
137
+ * @param vaultPath - Path to the vault database (default: ~/.hq-vault/vault.db)
138
+ * @returns Unlink result indicating what was removed
139
+ * @throws Error if the provider is not linked
140
+ */
141
+ export declare function unlinkProvider(providerName: string, vaultPath?: string): Promise<UnlinkResult>;
142
+ /**
143
+ * Error thrown when multiple OAuth providers are linked and no specific
144
+ * provider was requested. The caller should present these to the user
145
+ * and re-call with a specific provider.
146
+ */
147
+ export declare class MultipleProvidersError extends Error {
148
+ readonly providers: LinkedProvider[];
149
+ constructor(providers: LinkedProvider[]);
150
+ }
151
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/oauth/commands.ts"],"names":[],"mappings":"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"}