@everywheredev/cli 0.0.5 → 0.0.7

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 (307) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +274 -59
  3. package/package.json +3 -2
  4. package/scripts/build.mjs +68 -0
  5. package/dist/agent/agent-loop.d.ts +0 -40
  6. package/dist/agent/agent-loop.d.ts.map +0 -1
  7. package/dist/agent/agent-loop.js +0 -162
  8. package/dist/agent/agent-loop.js.map +0 -1
  9. package/dist/agent/approval.d.ts +0 -38
  10. package/dist/agent/approval.d.ts.map +0 -1
  11. package/dist/agent/approval.js +0 -55
  12. package/dist/agent/approval.js.map +0 -1
  13. package/dist/agent/run-tracker.d.ts +0 -26
  14. package/dist/agent/run-tracker.d.ts.map +0 -1
  15. package/dist/agent/run-tracker.js +0 -43
  16. package/dist/agent/run-tracker.js.map +0 -1
  17. package/dist/auth/device-flow.d.ts +0 -61
  18. package/dist/auth/device-flow.d.ts.map +0 -1
  19. package/dist/auth/device-flow.js +0 -141
  20. package/dist/auth/device-flow.js.map +0 -1
  21. package/dist/auth/hydra-oauth-auth-provider.d.ts +0 -35
  22. package/dist/auth/hydra-oauth-auth-provider.d.ts.map +0 -1
  23. package/dist/auth/hydra-oauth-auth-provider.js +0 -153
  24. package/dist/auth/hydra-oauth-auth-provider.js.map +0 -1
  25. package/dist/auth/keychain.d.ts +0 -42
  26. package/dist/auth/keychain.d.ts.map +0 -1
  27. package/dist/auth/keychain.js +0 -138
  28. package/dist/auth/keychain.js.map +0 -1
  29. package/dist/auth/pkce.d.ts +0 -20
  30. package/dist/auth/pkce.d.ts.map +0 -1
  31. package/dist/auth/pkce.js +0 -44
  32. package/dist/auth/pkce.js.map +0 -1
  33. package/dist/auth/ports.d.ts +0 -25
  34. package/dist/auth/ports.d.ts.map +0 -1
  35. package/dist/auth/ports.js +0 -8
  36. package/dist/auth/ports.js.map +0 -1
  37. package/dist/commands/activity.d.ts +0 -17
  38. package/dist/commands/activity.d.ts.map +0 -1
  39. package/dist/commands/activity.js +0 -54
  40. package/dist/commands/activity.js.map +0 -1
  41. package/dist/commands/agent.d.ts +0 -25
  42. package/dist/commands/agent.d.ts.map +0 -1
  43. package/dist/commands/agent.js +0 -80
  44. package/dist/commands/agent.js.map +0 -1
  45. package/dist/commands/agents.d.ts +0 -9
  46. package/dist/commands/agents.d.ts.map +0 -1
  47. package/dist/commands/agents.js +0 -28
  48. package/dist/commands/agents.js.map +0 -1
  49. package/dist/commands/commits.d.ts +0 -16
  50. package/dist/commands/commits.d.ts.map +0 -1
  51. package/dist/commands/commits.js +0 -39
  52. package/dist/commands/commits.js.map +0 -1
  53. package/dist/commands/diff.d.ts +0 -15
  54. package/dist/commands/diff.d.ts.map +0 -1
  55. package/dist/commands/diff.js +0 -27
  56. package/dist/commands/diff.js.map +0 -1
  57. package/dist/commands/expose.d.ts +0 -15
  58. package/dist/commands/expose.d.ts.map +0 -1
  59. package/dist/commands/expose.js +0 -39
  60. package/dist/commands/expose.js.map +0 -1
  61. package/dist/commands/index.d.ts +0 -7
  62. package/dist/commands/index.d.ts.map +0 -1
  63. package/dist/commands/index.js +0 -12
  64. package/dist/commands/index.js.map +0 -1
  65. package/dist/commands/login.d.ts +0 -9
  66. package/dist/commands/login.d.ts.map +0 -1
  67. package/dist/commands/login.js +0 -27
  68. package/dist/commands/login.js.map +0 -1
  69. package/dist/commands/logout.d.ts +0 -9
  70. package/dist/commands/logout.d.ts.map +0 -1
  71. package/dist/commands/logout.js +0 -24
  72. package/dist/commands/logout.js.map +0 -1
  73. package/dist/commands/me.d.ts +0 -10
  74. package/dist/commands/me.d.ts.map +0 -1
  75. package/dist/commands/me.js +0 -25
  76. package/dist/commands/me.js.map +0 -1
  77. package/dist/commands/open.d.ts +0 -16
  78. package/dist/commands/open.d.ts.map +0 -1
  79. package/dist/commands/open.js +0 -34
  80. package/dist/commands/open.js.map +0 -1
  81. package/dist/commands/ports.d.ts +0 -75
  82. package/dist/commands/ports.d.ts.map +0 -1
  83. package/dist/commands/ports.js +0 -78
  84. package/dist/commands/ports.js.map +0 -1
  85. package/dist/commands/profile.d.ts +0 -21
  86. package/dist/commands/profile.d.ts.map +0 -1
  87. package/dist/commands/profile.js +0 -93
  88. package/dist/commands/profile.js.map +0 -1
  89. package/dist/commands/push.d.ts +0 -18
  90. package/dist/commands/push.d.ts.map +0 -1
  91. package/dist/commands/push.js +0 -116
  92. package/dist/commands/push.js.map +0 -1
  93. package/dist/commands/registry.d.ts +0 -15
  94. package/dist/commands/registry.d.ts.map +0 -1
  95. package/dist/commands/registry.js +0 -45
  96. package/dist/commands/registry.js.map +0 -1
  97. package/dist/commands/request.d.ts +0 -25
  98. package/dist/commands/request.d.ts.map +0 -1
  99. package/dist/commands/request.js +0 -58
  100. package/dist/commands/request.js.map +0 -1
  101. package/dist/commands/resume.d.ts +0 -22
  102. package/dist/commands/resume.d.ts.map +0 -1
  103. package/dist/commands/resume.js +0 -69
  104. package/dist/commands/resume.js.map +0 -1
  105. package/dist/commands/save.d.ts +0 -34
  106. package/dist/commands/save.d.ts.map +0 -1
  107. package/dist/commands/save.js +0 -141
  108. package/dist/commands/save.js.map +0 -1
  109. package/dist/commands/session.d.ts +0 -9
  110. package/dist/commands/session.d.ts.map +0 -1
  111. package/dist/commands/session.js +0 -282
  112. package/dist/commands/session.js.map +0 -1
  113. package/dist/commands/skills/markdown-loader.d.ts +0 -19
  114. package/dist/commands/skills/markdown-loader.d.ts.map +0 -1
  115. package/dist/commands/skills/markdown-loader.js +0 -108
  116. package/dist/commands/skills/markdown-loader.js.map +0 -1
  117. package/dist/commands/skills/registry.d.ts +0 -23
  118. package/dist/commands/skills/registry.d.ts.map +0 -1
  119. package/dist/commands/skills/registry.js +0 -45
  120. package/dist/commands/skills/registry.js.map +0 -1
  121. package/dist/commands/terminal.d.ts +0 -19
  122. package/dist/commands/terminal.d.ts.map +0 -1
  123. package/dist/commands/terminal.js +0 -39
  124. package/dist/commands/terminal.js.map +0 -1
  125. package/dist/commands/tree.d.ts +0 -16
  126. package/dist/commands/tree.d.ts.map +0 -1
  127. package/dist/commands/tree.js +0 -44
  128. package/dist/commands/tree.js.map +0 -1
  129. package/dist/commands/undo.d.ts +0 -18
  130. package/dist/commands/undo.d.ts.map +0 -1
  131. package/dist/commands/undo.js +0 -46
  132. package/dist/commands/undo.js.map +0 -1
  133. package/dist/config/config-store.d.ts +0 -19
  134. package/dist/config/config-store.d.ts.map +0 -1
  135. package/dist/config/config-store.js +0 -199
  136. package/dist/config/config-store.js.map +0 -1
  137. package/dist/config/defaults.d.ts +0 -22
  138. package/dist/config/defaults.d.ts.map +0 -1
  139. package/dist/config/defaults.js +0 -38
  140. package/dist/config/defaults.js.map +0 -1
  141. package/dist/config/ports.d.ts +0 -60
  142. package/dist/config/ports.d.ts.map +0 -1
  143. package/dist/config/ports.js +0 -8
  144. package/dist/config/ports.js.map +0 -1
  145. package/dist/config/profile-constants.d.ts +0 -4
  146. package/dist/config/profile-constants.d.ts.map +0 -1
  147. package/dist/config/profile-constants.js +0 -10
  148. package/dist/config/profile-constants.js.map +0 -1
  149. package/dist/config/profile.d.ts +0 -84
  150. package/dist/config/profile.d.ts.map +0 -1
  151. package/dist/config/profile.js +0 -66
  152. package/dist/config/profile.js.map +0 -1
  153. package/dist/contract/index.d.ts +0 -193
  154. package/dist/contract/index.d.ts.map +0 -1
  155. package/dist/contract/index.js +0 -14
  156. package/dist/contract/index.js.map +0 -1
  157. package/dist/core/app.d.ts +0 -35
  158. package/dist/core/app.d.ts.map +0 -1
  159. package/dist/core/app.js +0 -86
  160. package/dist/core/app.js.map +0 -1
  161. package/dist/core/command-router.d.ts +0 -29
  162. package/dist/core/command-router.d.ts.map +0 -1
  163. package/dist/core/command-router.js +0 -61
  164. package/dist/core/command-router.js.map +0 -1
  165. package/dist/core/errors.d.ts +0 -39
  166. package/dist/core/errors.d.ts.map +0 -1
  167. package/dist/core/errors.js +0 -106
  168. package/dist/core/errors.js.map +0 -1
  169. package/dist/core/preflight.d.ts +0 -16
  170. package/dist/core/preflight.d.ts.map +0 -1
  171. package/dist/core/preflight.js +0 -38
  172. package/dist/core/preflight.js.map +0 -1
  173. package/dist/core/repl.d.ts +0 -18
  174. package/dist/core/repl.d.ts.map +0 -1
  175. package/dist/core/repl.js +0 -128
  176. package/dist/core/repl.js.map +0 -1
  177. package/dist/di/container.d.ts +0 -13
  178. package/dist/di/container.d.ts.map +0 -1
  179. package/dist/di/container.js +0 -160
  180. package/dist/di/container.js.map +0 -1
  181. package/dist/di/tokens.d.ts +0 -20
  182. package/dist/di/tokens.d.ts.map +0 -1
  183. package/dist/di/tokens.js +0 -22
  184. package/dist/di/tokens.js.map +0 -1
  185. package/dist/index.d.ts +0 -9
  186. package/dist/index.d.ts.map +0 -1
  187. package/dist/index.js.map +0 -1
  188. package/dist/render/ink-renderer.d.ts +0 -28
  189. package/dist/render/ink-renderer.d.ts.map +0 -1
  190. package/dist/render/ink-renderer.js +0 -174
  191. package/dist/render/ink-renderer.js.map +0 -1
  192. package/dist/render/plain-renderer.d.ts +0 -16
  193. package/dist/render/plain-renderer.d.ts.map +0 -1
  194. package/dist/render/plain-renderer.js +0 -38
  195. package/dist/render/plain-renderer.js.map +0 -1
  196. package/dist/render/ports.d.ts +0 -12
  197. package/dist/render/ports.d.ts.map +0 -1
  198. package/dist/render/ports.js +0 -10
  199. package/dist/render/ports.js.map +0 -1
  200. package/dist/render/raw-renderer.d.ts +0 -11
  201. package/dist/render/raw-renderer.d.ts.map +0 -1
  202. package/dist/render/raw-renderer.js +0 -68
  203. package/dist/render/raw-renderer.js.map +0 -1
  204. package/dist/render/repl-input.d.ts +0 -15
  205. package/dist/render/repl-input.d.ts.map +0 -1
  206. package/dist/render/repl-input.js +0 -102
  207. package/dist/render/repl-input.js.map +0 -1
  208. package/dist/session/file-session-store.d.ts +0 -26
  209. package/dist/session/file-session-store.d.ts.map +0 -1
  210. package/dist/session/file-session-store.js +0 -174
  211. package/dist/session/file-session-store.js.map +0 -1
  212. package/dist/session/ports.d.ts +0 -50
  213. package/dist/session/ports.d.ts.map +0 -1
  214. package/dist/session/ports.js +0 -6
  215. package/dist/session/ports.js.map +0 -1
  216. package/dist/sync/git-sync.d.ts +0 -16
  217. package/dist/sync/git-sync.d.ts.map +0 -1
  218. package/dist/sync/git-sync.js +0 -28
  219. package/dist/sync/git-sync.js.map +0 -1
  220. package/dist/sync/git.d.ts +0 -12
  221. package/dist/sync/git.d.ts.map +0 -1
  222. package/dist/sync/git.js +0 -100
  223. package/dist/sync/git.js.map +0 -1
  224. package/dist/sync/reconciler.d.ts +0 -36
  225. package/dist/sync/reconciler.d.ts.map +0 -1
  226. package/dist/sync/reconciler.js +0 -143
  227. package/dist/sync/reconciler.js.map +0 -1
  228. package/dist/sync/walk.d.ts +0 -23
  229. package/dist/sync/walk.d.ts.map +0 -1
  230. package/dist/sync/walk.js +0 -81
  231. package/dist/sync/walk.js.map +0 -1
  232. package/dist/sync/watch.d.ts +0 -13
  233. package/dist/sync/watch.d.ts.map +0 -1
  234. package/dist/sync/watch.js +0 -75
  235. package/dist/sync/watch.js.map +0 -1
  236. package/dist/tools/git-diff.d.ts +0 -16
  237. package/dist/tools/git-diff.d.ts.map +0 -1
  238. package/dist/tools/git-diff.js +0 -25
  239. package/dist/tools/git-diff.js.map +0 -1
  240. package/dist/tools/http-request.d.ts +0 -25
  241. package/dist/tools/http-request.d.ts.map +0 -1
  242. package/dist/tools/http-request.js +0 -41
  243. package/dist/tools/http-request.js.map +0 -1
  244. package/dist/tools/index.d.ts +0 -7
  245. package/dist/tools/index.d.ts.map +0 -1
  246. package/dist/tools/index.js +0 -22
  247. package/dist/tools/index.js.map +0 -1
  248. package/dist/tools/ports.d.ts +0 -58
  249. package/dist/tools/ports.d.ts.map +0 -1
  250. package/dist/tools/ports.js +0 -17
  251. package/dist/tools/ports.js.map +0 -1
  252. package/dist/tools/read-file.d.ts +0 -16
  253. package/dist/tools/read-file.d.ts.map +0 -1
  254. package/dist/tools/read-file.js +0 -24
  255. package/dist/tools/read-file.js.map +0 -1
  256. package/dist/tools/registry.d.ts +0 -10
  257. package/dist/tools/registry.d.ts.map +0 -1
  258. package/dist/tools/registry.js +0 -28
  259. package/dist/tools/registry.js.map +0 -1
  260. package/dist/tools/run-command.d.ts +0 -20
  261. package/dist/tools/run-command.d.ts.map +0 -1
  262. package/dist/tools/run-command.js +0 -65
  263. package/dist/tools/run-command.js.map +0 -1
  264. package/dist/tools/write-file.d.ts +0 -24
  265. package/dist/tools/write-file.d.ts.map +0 -1
  266. package/dist/tools/write-file.js +0 -60
  267. package/dist/tools/write-file.js.map +0 -1
  268. package/dist/transport/composite-transport.d.ts +0 -30
  269. package/dist/transport/composite-transport.d.ts.map +0 -1
  270. package/dist/transport/composite-transport.js +0 -71
  271. package/dist/transport/composite-transport.js.map +0 -1
  272. package/dist/transport/device-browser.d.ts +0 -19
  273. package/dist/transport/device-browser.d.ts.map +0 -1
  274. package/dist/transport/device-browser.js +0 -243
  275. package/dist/transport/device-browser.js.map +0 -1
  276. package/dist/transport/device-git.d.ts +0 -14
  277. package/dist/transport/device-git.d.ts.map +0 -1
  278. package/dist/transport/device-git.js +0 -107
  279. package/dist/transport/device-git.js.map +0 -1
  280. package/dist/transport/device-http.d.ts +0 -10
  281. package/dist/transport/device-http.d.ts.map +0 -1
  282. package/dist/transport/device-http.js +0 -96
  283. package/dist/transport/device-http.js.map +0 -1
  284. package/dist/transport/device-terminal.d.ts +0 -44
  285. package/dist/transport/device-terminal.d.ts.map +0 -1
  286. package/dist/transport/device-terminal.js +0 -140
  287. package/dist/transport/device-terminal.js.map +0 -1
  288. package/dist/transport/http-transport.d.ts +0 -26
  289. package/dist/transport/http-transport.d.ts.map +0 -1
  290. package/dist/transport/http-transport.js +0 -125
  291. package/dist/transport/http-transport.js.map +0 -1
  292. package/dist/transport/ports.d.ts +0 -67
  293. package/dist/transport/ports.d.ts.map +0 -1
  294. package/dist/transport/ports.js +0 -11
  295. package/dist/transport/ports.js.map +0 -1
  296. package/dist/transport/reconnect.d.ts +0 -44
  297. package/dist/transport/reconnect.d.ts.map +0 -1
  298. package/dist/transport/reconnect.js +0 -69
  299. package/dist/transport/reconnect.js.map +0 -1
  300. package/dist/transport/terminal-transport.d.ts +0 -28
  301. package/dist/transport/terminal-transport.d.ts.map +0 -1
  302. package/dist/transport/terminal-transport.js +0 -63
  303. package/dist/transport/terminal-transport.js.map +0 -1
  304. package/dist/transport/ws-stream-transport.d.ts +0 -66
  305. package/dist/transport/ws-stream-transport.d.ts.map +0 -1
  306. package/dist/transport/ws-stream-transport.js +0 -246
  307. package/dist/transport/ws-stream-transport.js.map +0 -1
@@ -1,141 +0,0 @@
1
- // Device Authorization Grant (RFC 8628) + PKCE helper.
2
- //
3
- // SRP: this module performs the OAuth2 device flow against Ory Hydra and nothing else — discovery,
4
- // device-authorization request, and polling the token endpoint. It returns a `TokenSet`; it does not
5
- // store tokens, build headers, or know about the transport. The HydraOAuthAuthProvider orchestrates
6
- // it and persists results in the Keychain.
7
- import { CliError } from "../core/errors.js";
8
- import { createPkcePair } from "./pkce.js";
9
- export class DeviceFlow {
10
- cfg;
11
- fetchImpl;
12
- sleep;
13
- constructor(cfg, fetchImpl = fetch, sleep = defaultSleep) {
14
- this.cfg = cfg;
15
- this.fetchImpl = fetchImpl;
16
- this.sleep = sleep;
17
- }
18
- /** Discover the OIDC endpoints via /.well-known/openid-configuration. */
19
- async discover() {
20
- const url = `${trimSlash(this.cfg.oidcIssuer)}/.well-known/openid-configuration`;
21
- const res = await this.fetchImpl(url, { headers: { accept: "application/json" } });
22
- if (!res.ok) {
23
- throw CliError.auth(`OIDC discovery failed (${res.status}).`, `Check the profile's oidcIssuer (${this.cfg.oidcIssuer}).`);
24
- }
25
- return (await res.json());
26
- }
27
- /**
28
- * Run the full grant: discover → request device code (with PKCE challenge) → prompt → poll.
29
- * Resolves with a TokenSet (access + optional refresh/id tokens) on user approval.
30
- */
31
- async authorize(prompt) {
32
- const disc = await this.discover();
33
- const pkce = await createPkcePair();
34
- // Device authorization request (PKCE challenge bound here, verifier sent at token time).
35
- const authBody = new URLSearchParams({
36
- client_id: this.cfg.clientId,
37
- scope: this.cfg.scopes.join(" "),
38
- code_challenge: pkce.codeChallenge,
39
- code_challenge_method: pkce.method,
40
- });
41
- const authRes = await this.fetchImpl(disc.device_authorization_endpoint, {
42
- method: "POST",
43
- headers: form(),
44
- body: authBody.toString(),
45
- });
46
- if (!authRes.ok) {
47
- throw CliError.auth(`Device authorization request failed (${authRes.status}).`);
48
- }
49
- const device = (await authRes.json());
50
- prompt({
51
- userCode: device.user_code,
52
- verificationUri: device.verification_uri,
53
- verificationUriComplete: device.verification_uri_complete,
54
- expiresIn: device.expires_in,
55
- });
56
- return this.poll(disc, device, pkce.codeVerifier);
57
- }
58
- /** Refresh an access token using a refresh_token grant. */
59
- async refresh(refreshToken) {
60
- const disc = await this.discover();
61
- const body = new URLSearchParams({
62
- grant_type: "refresh_token",
63
- client_id: this.cfg.clientId,
64
- refresh_token: refreshToken,
65
- });
66
- const res = await this.fetchImpl(disc.token_endpoint, {
67
- method: "POST",
68
- headers: form(),
69
- body: body.toString(),
70
- });
71
- if (!res.ok) {
72
- throw CliError.auth("Token refresh failed.", "Run `pocketdev login` to re-authenticate.");
73
- }
74
- return stamp((await res.json()));
75
- }
76
- /** Revoke a token (refresh or access) at logout, if the issuer exposes a revocation endpoint. */
77
- async revoke(token) {
78
- const disc = await this.discover();
79
- if (!disc.revocation_endpoint)
80
- return;
81
- const body = new URLSearchParams({ client_id: this.cfg.clientId, token });
82
- await this.fetchImpl(disc.revocation_endpoint, {
83
- method: "POST",
84
- headers: form(),
85
- body: body.toString(),
86
- }).catch(() => undefined);
87
- }
88
- // ── polling loop (handles authorization_pending / slow_down per RFC 8628 §3.5) ──
89
- async poll(disc, device, codeVerifier) {
90
- let intervalMs = (device.interval ?? 5) * 1000;
91
- const deadline = Date.now() + device.expires_in * 1000;
92
- while (Date.now() < deadline) {
93
- await this.sleep(intervalMs);
94
- const body = new URLSearchParams({
95
- grant_type: "urn:ietf:params:oauth:grant-type:device_code",
96
- client_id: this.cfg.clientId,
97
- device_code: device.device_code,
98
- code_verifier: codeVerifier,
99
- });
100
- const res = await this.fetchImpl(disc.token_endpoint, {
101
- method: "POST",
102
- headers: form(),
103
- body: body.toString(),
104
- });
105
- if (res.ok) {
106
- return stamp((await res.json()));
107
- }
108
- const err = (await res.json().catch(() => ({})));
109
- switch (err.error) {
110
- case "authorization_pending":
111
- continue; // keep polling at the current interval
112
- case "slow_down":
113
- intervalMs += 5000; // RFC 8628: back off by 5s
114
- continue;
115
- case "access_denied":
116
- throw CliError.auth("Authorization was denied.");
117
- case "expired_token":
118
- throw CliError.auth("The device code expired.", "Run `pocketdev login` again.");
119
- default:
120
- throw CliError.auth(`Device token poll failed: ${err.error ?? res.status}.`);
121
- }
122
- }
123
- throw CliError.auth("Timed out waiting for device authorization.", "Run `pocketdev login` again.");
124
- }
125
- }
126
- function stamp(t) {
127
- if (t.expires_in && !t.expiresAt) {
128
- return { ...t, expiresAt: Date.now() + t.expires_in * 1000 };
129
- }
130
- return t;
131
- }
132
- function form() {
133
- return { "content-type": "application/x-www-form-urlencoded", accept: "application/json" };
134
- }
135
- function trimSlash(s) {
136
- return s.endsWith("/") ? s.slice(0, -1) : s;
137
- }
138
- function defaultSleep(ms) {
139
- return new Promise((r) => setTimeout(r, ms));
140
- }
141
- //# sourceMappingURL=device-flow.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"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"}
@@ -1,35 +0,0 @@
1
- import type { ConfigStore } from "../config/ports.js";
2
- import { DeviceFlow, type DevicePrompt } from "./device-flow.js";
3
- import type { Keychain } from "./keychain.js";
4
- import type { AuthProvider, BearerSource } from "./ports.js";
5
- export declare class HydraOAuthAuthProvider implements AuthProvider, BearerSource {
6
- private readonly config;
7
- private readonly keychain;
8
- /** Surfaces the device code/URL to the user; injected so this stays renderer-agnostic. */
9
- private readonly devicePrompt;
10
- /** Allows tests to inject a stubbed DeviceFlow. */
11
- private readonly makeFlow;
12
- private tokens?;
13
- private loaded;
14
- constructor(config: ConfigStore, keychain: Keychain,
15
- /** Surfaces the device code/URL to the user; injected so this stays renderer-agnostic. */
16
- devicePrompt?: DevicePrompt,
17
- /** Allows tests to inject a stubbed DeviceFlow. */
18
- makeFlow?: (cfg: ConfigStore) => DeviceFlow);
19
- getAuthHeader(): Promise<string>;
20
- bearerToken(): Promise<string>;
21
- /** Interactive sign-in via the device grant; persists the TokenSet to the keychain. */
22
- login(): Promise<void>;
23
- /** Revoke (best-effort) and clear cached + persisted credentials. */
24
- logout(): Promise<void>;
25
- /** Proactive/forced refresh. Returns false when no refresh token is available. */
26
- refresh(): Promise<boolean>;
27
- /** Stable subject id from the access token's `sub` claim (for transcript attribution). */
28
- subject(): string;
29
- private ensureValidToken;
30
- private isExpiring;
31
- private load;
32
- private store;
33
- private account;
34
- }
35
- //# sourceMappingURL=hydra-oauth-auth-provider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hydra-oauth-auth-provider.d.ts","sourceRoot":"","sources":["../../src/auth/hydra-oauth-auth-provider.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAiB,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ7D,qBAAa,sBAAuB,YAAW,YAAY,EAAE,YAAY;IAKrE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,MAAM,CAAS;gBAGJ,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,QAAQ;IACnC,0FAA0F;IACzE,YAAY,GAAE,YAA4B;IAC3D,mDAAmD;IAClC,QAAQ,GAAE,CAAC,GAAG,EAAE,WAAW,KAAK,UAA4B;IAGzE,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAKpC,uFAAuF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,qEAAqE;IAC/D,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAU7B,kFAAkF;IAC5E,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAejC,0FAA0F;IAC1F,OAAO,IAAI,MAAM;YAYH,gBAAgB;IAiB9B,OAAO,CAAC,UAAU;YAKJ,IAAI;YAaJ,KAAK;IAMnB,OAAO,CAAC,OAAO;CAGhB"}
@@ -1,153 +0,0 @@
1
- // HydraOAuthAuthProvider — FULL-REMOTE authentication.
2
- //
3
- // SRP: orchestrates the OAuth2 Device Authorization Grant + PKCE (via DeviceFlow), caches the
4
- // resulting TokenSet, persists it in the Keychain, refreshes proactively before expiry, and yields a
5
- // `Bearer <access_jwt>` header. It owns token lifecycle and nothing else (the device-flow HTTP lives
6
- // in device-flow.ts; storage in keychain.ts).
7
- //
8
- // DIP: depends on the `Keychain` interface and a `DevicePrompt` callback, never on a concrete
9
- // keyring or the renderer.
10
- import { decodeJwt } from "jose";
11
- import { CliError } from "../core/errors.js";
12
- import { DeviceFlow } from "./device-flow.js";
13
- /** Keychain account under which the serialized TokenSet is stored, namespaced per profile. */
14
- const ACCOUNT_PREFIX = "hydra-tokens";
15
- /** Refresh this many ms before the access token's stated expiry to avoid mid-request 401s. */
16
- const REFRESH_SKEW_MS = 60_000;
17
- export class HydraOAuthAuthProvider {
18
- config;
19
- keychain;
20
- devicePrompt;
21
- makeFlow;
22
- tokens;
23
- loaded = false;
24
- constructor(config, keychain,
25
- /** Surfaces the device code/URL to the user; injected so this stays renderer-agnostic. */
26
- devicePrompt = defaultPrompt,
27
- /** Allows tests to inject a stubbed DeviceFlow. */
28
- makeFlow = makeDefaultFlow) {
29
- this.config = config;
30
- this.keychain = keychain;
31
- this.devicePrompt = devicePrompt;
32
- this.makeFlow = makeFlow;
33
- }
34
- async getAuthHeader() {
35
- const t = await this.ensureValidToken();
36
- return `Bearer ${t.access_token}`;
37
- }
38
- async bearerToken() {
39
- const t = await this.ensureValidToken();
40
- return t.access_token;
41
- }
42
- /** Interactive sign-in via the device grant; persists the TokenSet to the keychain. */
43
- async login() {
44
- const flow = this.makeFlow(this.config);
45
- const tokens = await flow.authorize(this.devicePrompt);
46
- await this.store(tokens);
47
- }
48
- /** Revoke (best-effort) and clear cached + persisted credentials. */
49
- async logout() {
50
- await this.load();
51
- const refresh = this.tokens?.refresh_token;
52
- if (refresh) {
53
- await this.makeFlow(this.config).revoke(refresh).catch(() => undefined);
54
- }
55
- this.tokens = undefined;
56
- await this.keychain.delete(this.account());
57
- }
58
- /** Proactive/forced refresh. Returns false when no refresh token is available. */
59
- async refresh() {
60
- await this.load();
61
- const refresh = this.tokens?.refresh_token;
62
- if (!refresh)
63
- return false;
64
- try {
65
- const next = await this.makeFlow(this.config).refresh(refresh);
66
- // Hydra may not re-issue a refresh token; keep the prior one if absent.
67
- if (!next.refresh_token)
68
- next.refresh_token = refresh;
69
- await this.store(next);
70
- return true;
71
- }
72
- catch {
73
- return false;
74
- }
75
- }
76
- /** Stable subject id from the access token's `sub` claim (for transcript attribution). */
77
- subject() {
78
- if (!this.tokens?.access_token)
79
- return "remote";
80
- try {
81
- const claims = decodeJwt(this.tokens.access_token);
82
- return typeof claims.sub === "string" ? claims.sub : "remote";
83
- }
84
- catch {
85
- return "remote";
86
- }
87
- }
88
- // ── internals ───────────────────────────────────────────────────────────────
89
- async ensureValidToken() {
90
- await this.load();
91
- if (!this.tokens?.access_token) {
92
- throw CliError.auth("Not signed in.", "Run `pocketdev login`.");
93
- }
94
- if (this.isExpiring(this.tokens)) {
95
- const ok = await this.refresh();
96
- if (!ok) {
97
- throw CliError.auth("Session expired and could not be refreshed.", "Run `pocketdev login`.");
98
- }
99
- }
100
- return this.tokens;
101
- }
102
- isExpiring(t) {
103
- if (!t.expiresAt)
104
- return false; // no stated expiry → trust until the host returns 401
105
- return Date.now() >= t.expiresAt - REFRESH_SKEW_MS;
106
- }
107
- async load() {
108
- if (this.loaded)
109
- return;
110
- this.loaded = true;
111
- const raw = await this.keychain.get(this.account());
112
- if (raw) {
113
- try {
114
- this.tokens = JSON.parse(raw);
115
- }
116
- catch {
117
- this.tokens = undefined;
118
- }
119
- }
120
- }
121
- async store(tokens) {
122
- this.tokens = tokens;
123
- this.loaded = true;
124
- await this.keychain.set(this.account(), JSON.stringify(tokens));
125
- }
126
- account() {
127
- return `${ACCOUNT_PREFIX}:${this.config.profile().name}`;
128
- }
129
- }
130
- function makeDefaultFlow(config) {
131
- const profile = config.profile();
132
- const resolved = config.resolve();
133
- const issuer = resolved.oidcIssuer ?? profile.oidcIssuer;
134
- if (!issuer) {
135
- throw CliError.config(`Remote profile "${profile.name}" has no OIDC issuer.`, "Set OIDC_ISSUER or add oidcIssuer to the profile in ~/.pocketdev/config.json.");
136
- }
137
- if (!profile.clientId) {
138
- throw CliError.config(`Remote profile "${profile.name}" has no clientId.`);
139
- }
140
- return new DeviceFlow({
141
- oidcIssuer: issuer,
142
- clientId: profile.clientId,
143
- scopes: profile.scopes ?? [],
144
- });
145
- }
146
- /** Default prompt prints the device instructions to stderr so it works even in pipe mode. */
147
- const defaultPrompt = (info) => {
148
- const target = info.verificationUriComplete ?? info.verificationUri;
149
- process.stderr.write(`\nTo sign in, open:\n ${target}\n` +
150
- (info.verificationUriComplete ? "" : `and enter the code: ${info.userCode}\n`) +
151
- `(expires in ${Math.floor(info.expiresIn / 60)}m)\n\n`);
152
- };
153
- //# sourceMappingURL=hydra-oauth-auth-provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hydra-oauth-auth-provider.js","sourceRoot":"","sources":["../../src/auth/hydra-oauth-auth-provider.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,8FAA8F;AAC9F,qGAAqG;AACrG,qGAAqG;AACrG,8CAA8C;AAC9C,EAAE;AACF,8FAA8F;AAC9F,2BAA2B;AAE3B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAoC,MAAM,kBAAkB,CAAC;AAIhF,8FAA8F;AAC9F,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC,8FAA8F;AAC9F,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,MAAM,OAAO,sBAAsB;IAKd;IACA;IAEA;IAEA;IATX,MAAM,CAAY;IAClB,MAAM,GAAG,KAAK,CAAC;IAEvB,YACmB,MAAmB,EACnB,QAAkB;IACnC,0FAA0F;IACzE,eAA6B,aAAa;IAC3D,mDAAmD;IAClC,WAA6C,eAAe;QAL5D,WAAM,GAAN,MAAM,CAAa;QACnB,aAAQ,GAAR,QAAQ,CAAU;QAElB,iBAAY,GAAZ,YAAY,CAA8B;QAE1C,aAAQ,GAAR,QAAQ,CAAoD;IAC5E,CAAC;IAEJ,KAAK,CAAC,aAAa;QACjB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,CAAC,YAAY,EAAE,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxC,OAAO,CAAC,CAAC,YAAY,CAAC;IACxB,CAAC;IAED,uFAAuF;IACvF,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/D,wEAAwE;YACxE,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;YACtD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,0FAA0F;IAC1F,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY;YAAE,OAAO,QAAQ,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACnD,OAAO,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,+EAA+E;IAEvE,KAAK,CAAC,gBAAgB;QAC5B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC;YAC/B,MAAM,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,wBAAwB,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,MAAM,QAAQ,CAAC,IAAI,CACjB,6CAA6C,EAC7C,wBAAwB,CACzB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,UAAU,CAAC,CAAW;QAC5B,IAAI,CAAC,CAAC,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC,CAAC,sDAAsD;QACtF,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,SAAS,GAAG,eAAe,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACpD,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,MAAgB;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,CAAC;IAEO,OAAO;QACb,OAAO,GAAG,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;CACF;AAED,SAAS,eAAe,CAAC,MAAmB;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IACzD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,QAAQ,CAAC,MAAM,CACnB,mBAAmB,OAAO,CAAC,IAAI,uBAAuB,EACtD,+EAA+E,CAChF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtB,MAAM,QAAQ,CAAC,MAAM,CAAC,mBAAmB,OAAO,CAAC,IAAI,oBAAoB,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,IAAI,UAAU,CAAC;QACpB,UAAU,EAAE,MAAM;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;KAC7B,CAAC,CAAC;AACL,CAAC;AAED,6FAA6F;AAC7F,MAAM,aAAa,GAAiB,CAAC,IAAI,EAAE,EAAE;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC,eAAe,CAAC;IACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0BAA0B,MAAM,IAAI;QAClC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB,IAAI,CAAC,QAAQ,IAAI,CAAC;QAC9E,eAAe,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,QAAQ,CACzD,CAAC;AACJ,CAAC,CAAC"}
@@ -1,42 +0,0 @@
1
- /** Narrow port: get/set/delete a secret by account. Service name is fixed per Keychain instance. */
2
- export interface Keychain {
3
- get(account: string): Promise<string | null>;
4
- set(account: string, secret: string): Promise<void>;
5
- delete(account: string): Promise<boolean>;
6
- }
7
- /**
8
- * OS-keychain-first Keychain with a 0600 file fallback.
9
- *
10
- * keytar is loaded lazily because it is a native module that may be absent on minimal CI images;
11
- * when it cannot load we transparently use the file store. This keeps `pocketdev login` working in
12
- * a pipeline pod without a desktop keyring.
13
- */
14
- export declare class OsKeychain implements Keychain {
15
- private readonly service;
16
- private keytar?;
17
- private readonly fallback;
18
- constructor(service?: string);
19
- get(account: string): Promise<string | null>;
20
- set(account: string, secret: string): Promise<void>;
21
- delete(account: string): Promise<boolean>;
22
- private loadKeytar;
23
- }
24
- /**
25
- * Plain-file credential store with restrictive permissions.
26
- *
27
- * Stores a JSON map { account: secret } at ~/.pocketdev/credentials.json with mode 0600. This is the
28
- * documented fallback for headless/CI; secrets here should be short-lived (refresh tokens, ideally
29
- * env-injected for non-interactive runs).
30
- */
31
- export declare class FileKeychain implements Keychain {
32
- private readonly service;
33
- private readonly file;
34
- constructor(service?: string);
35
- get(account: string): Promise<string | null>;
36
- set(account: string, secret: string): Promise<void>;
37
- delete(account: string): Promise<boolean>;
38
- private key;
39
- private read;
40
- private write;
41
- }
42
- //# sourceMappingURL=keychain.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"AAcA,oGAAoG;AACpG,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C;AAWD;;;;;;GAMG;AACH,qBAAa,UAAW,YAAW,QAAQ;IAI7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,MAAM,CAAC,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAEX,OAAO,GAAE,MAAgB;IAIhD,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAY5C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAanD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAcjC,UAAU;CAUzB;AAED;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAG/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAED,OAAO,GAAE,MAAgB;IAIhD,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAM5C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/C,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,KAAK;CAQd"}
@@ -1,138 +0,0 @@
1
- // Keychain — credential storage at rest.
2
- //
3
- // SRP: this module's single job is "persist/retrieve a secret string under (service, account)".
4
- // It prefers the OS keychain (macOS Keychain / libsecret / Windows Credential Manager via `keytar`)
5
- // and falls back to a chmod-0600 file under ~/.pocketdev for headless/CI machines where no keyring
6
- // daemon is available (docs §11/§15). The HydraOAuthAuthProvider depends on the `Keychain` interface
7
- // only — DIP — so tests substitute an in-memory fake.
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
- import { chmod } from "node:fs/promises";
10
- import { homedir } from "node:os";
11
- import { dirname, join } from "node:path";
12
- import { USER_DIR_NAME } from "../config/defaults.js";
13
- const SERVICE = "com.pocketdev.cli";
14
- /**
15
- * OS-keychain-first Keychain with a 0600 file fallback.
16
- *
17
- * keytar is loaded lazily because it is a native module that may be absent on minimal CI images;
18
- * when it cannot load we transparently use the file store. This keeps `pocketdev login` working in
19
- * a pipeline pod without a desktop keyring.
20
- */
21
- export class OsKeychain {
22
- service;
23
- keytar; // undefined = not tried, null = unavailable
24
- fallback;
25
- constructor(service = SERVICE) {
26
- this.service = service;
27
- this.fallback = new FileKeychain(service);
28
- }
29
- async get(account) {
30
- const kt = await this.loadKeytar();
31
- if (kt) {
32
- try {
33
- return await kt.getPassword(this.service, account);
34
- }
35
- catch {
36
- // fall through to file store
37
- }
38
- }
39
- return this.fallback.get(account);
40
- }
41
- async set(account, secret) {
42
- const kt = await this.loadKeytar();
43
- if (kt) {
44
- try {
45
- await kt.setPassword(this.service, account, secret);
46
- return;
47
- }
48
- catch {
49
- // fall through to file store
50
- }
51
- }
52
- await this.fallback.set(account, secret);
53
- }
54
- async delete(account) {
55
- const kt = await this.loadKeytar();
56
- let removed = false;
57
- if (kt) {
58
- try {
59
- removed = await kt.deletePassword(this.service, account);
60
- }
61
- catch {
62
- // ignore; also try file store
63
- }
64
- }
65
- const fileRemoved = await this.fallback.delete(account);
66
- return removed || fileRemoved;
67
- }
68
- async loadKeytar() {
69
- if (this.keytar !== undefined)
70
- return this.keytar;
71
- try {
72
- const mod = (await import("keytar"));
73
- this.keytar = mod.default ?? mod;
74
- }
75
- catch {
76
- this.keytar = null; // native module unavailable → use file fallback
77
- }
78
- return this.keytar;
79
- }
80
- }
81
- /**
82
- * Plain-file credential store with restrictive permissions.
83
- *
84
- * Stores a JSON map { account: secret } at ~/.pocketdev/credentials.json with mode 0600. This is the
85
- * documented fallback for headless/CI; secrets here should be short-lived (refresh tokens, ideally
86
- * env-injected for non-interactive runs).
87
- */
88
- export class FileKeychain {
89
- service;
90
- file;
91
- constructor(service = SERVICE) {
92
- this.service = service;
93
- this.file = join(homedir(), USER_DIR_NAME, "credentials.json");
94
- }
95
- async get(account) {
96
- const map = this.read();
97
- const v = map[this.key(account)];
98
- return v ?? null;
99
- }
100
- async set(account, secret) {
101
- const map = this.read();
102
- map[this.key(account)] = secret;
103
- this.write(map);
104
- }
105
- async delete(account) {
106
- const map = this.read();
107
- const k = this.key(account);
108
- if (!(k in map))
109
- return false;
110
- delete map[k];
111
- this.write(map);
112
- return true;
113
- }
114
- key(account) {
115
- return `${this.service}:${account}`;
116
- }
117
- read() {
118
- if (!existsSync(this.file))
119
- return {};
120
- try {
121
- const parsed = JSON.parse(readFileSync(this.file, "utf8"));
122
- return parsed && typeof parsed === "object" ? parsed : {};
123
- }
124
- catch {
125
- return {};
126
- }
127
- }
128
- write(map) {
129
- const dir = dirname(this.file);
130
- if (!existsSync(dir))
131
- mkdirSync(dir, { recursive: true, mode: 0o700 });
132
- // Write then tighten perms; { mode } on write does not lower an existing file's mode.
133
- writeFileSync(this.file, JSON.stringify(map, null, 2), { encoding: "utf8", mode: 0o600 });
134
- // Best-effort enforce 0600 even if the file pre-existed with looser perms.
135
- void chmod(this.file, 0o600).catch(() => undefined);
136
- }
137
- }
138
- //# sourceMappingURL=keychain.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- /** A PKCE pair: the secret verifier (sent at token time) and the S256 challenge (sent at auth time). */
2
- export interface PkcePair {
3
- codeVerifier: string;
4
- codeChallenge: string;
5
- /** Always "S256" — plain is not used. */
6
- method: "S256";
7
- }
8
- /** base64url-encode raw bytes without padding (RFC 4648 §5). */
9
- export declare function base64UrlEncode(bytes: Uint8Array): string;
10
- /** Generate `length` cryptographically-random bytes. */
11
- export declare function randomBytes(length: number): Uint8Array;
12
- /** Create a high-entropy code verifier (43–128 chars per RFC 7636 §4.1). */
13
- export declare function createCodeVerifier(): string;
14
- /** Compute the S256 code challenge for a verifier. */
15
- export declare function createCodeChallenge(verifier: string): Promise<string>;
16
- /** Convenience: generate a full PKCE pair. */
17
- export declare function createPkcePair(): Promise<PkcePair>;
18
- /** Opaque anti-CSRF state value. */
19
- export declare function createState(): string;
20
- //# sourceMappingURL=pkce.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAMA,wGAAwG;AACxG,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQzD;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAItD;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAED,sDAAsD;AACtD,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI3E;AAED,8CAA8C;AAC9C,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAIxD;AAED,oCAAoC;AACpC,wBAAgB,WAAW,IAAI,MAAM,CAEpC"}
package/dist/auth/pkce.js DELETED
@@ -1,44 +0,0 @@
1
- // PKCE (RFC 7636) helpers for the device-authorization grant.
2
- //
3
- // SRP: this module only mints a `code_verifier`/`code_challenge` pair and the random `state`. No HTTP,
4
- // no storage. Used by device-flow.ts. We use Node's WebCrypto (`globalThis.crypto`) for SHA-256 and
5
- // CSPRNG bytes so there is no extra dependency.
6
- /** base64url-encode raw bytes without padding (RFC 4648 §5). */
7
- export function base64UrlEncode(bytes) {
8
- let bin = "";
9
- for (const b of bytes)
10
- bin += String.fromCharCode(b);
11
- return Buffer.from(bin, "binary")
12
- .toString("base64")
13
- .replace(/\+/g, "-")
14
- .replace(/\//g, "_")
15
- .replace(/=+$/, "");
16
- }
17
- /** Generate `length` cryptographically-random bytes. */
18
- export function randomBytes(length) {
19
- const out = new Uint8Array(length);
20
- globalThis.crypto.getRandomValues(out);
21
- return out;
22
- }
23
- /** Create a high-entropy code verifier (43–128 chars per RFC 7636 §4.1). */
24
- export function createCodeVerifier() {
25
- // 32 random bytes → 43 base64url chars, comfortably within the allowed range.
26
- return base64UrlEncode(randomBytes(32));
27
- }
28
- /** Compute the S256 code challenge for a verifier. */
29
- export async function createCodeChallenge(verifier) {
30
- const data = new TextEncoder().encode(verifier);
31
- const digest = await globalThis.crypto.subtle.digest("SHA-256", data);
32
- return base64UrlEncode(new Uint8Array(digest));
33
- }
34
- /** Convenience: generate a full PKCE pair. */
35
- export async function createPkcePair() {
36
- const codeVerifier = createCodeVerifier();
37
- const codeChallenge = await createCodeChallenge(codeVerifier);
38
- return { codeVerifier, codeChallenge, method: "S256" };
39
- }
40
- /** Opaque anti-CSRF state value. */
41
- export function createState() {
42
- return base64UrlEncode(randomBytes(16));
43
- }
44
- //# sourceMappingURL=pkce.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,uGAAuG;AACvG,oGAAoG;AACpG,gDAAgD;AAUhD,gEAAgE;AAChE,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC;SAC9B,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,kBAAkB;IAChC,8EAA8E;IAC9E,OAAO,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACtE,OAAO,eAAe,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,8CAA8C;AAC9C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;IAC1C,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC9D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACzD,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,WAAW;IACzB,OAAO,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1C,CAAC"}
@@ -1,25 +0,0 @@
1
- export interface AuthProvider {
2
- /**
3
- * Returns the full `Authorization` header value, e.g. "Bearer eyJ…".
4
- * Refreshes proactively if the token is near expiry.
5
- */
6
- getAuthHeader(): Promise<string>;
7
- /** Interactive sign-in: the OAuth2 Device Authorization Grant + PKCE against Ory Hydra (RFC 8628). */
8
- login(): Promise<void>;
9
- /** Drop cached credentials: keychain entry + in-memory tokens. */
10
- logout(): Promise<void>;
11
- /**
12
- * Force a refresh (called once on a 401 before falling back to re-login).
13
- * Returns false when refresh is impossible (no refresh token).
14
- */
15
- refresh(): Promise<boolean>;
16
- /** Stable subject id for transcript attribution: the `sub` claim. */
17
- subject(): string;
18
- }
19
- /** Optional capability some providers expose for the WS handshake (token, not just header). */
20
- export interface BearerSource {
21
- /** Raw bearer token (without the "Bearer " prefix) for `?token=` / handshake header reuse. */
22
- bearerToken(): Promise<string>;
23
- }
24
- export declare function hasBearerSource(p: AuthProvider): p is AuthProvider & BearerSource;
25
- //# sourceMappingURL=ports.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/auth/ports.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjC,sGAAsG;IACtG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,kEAAkE;IAClE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5B,qEAAqE;IACrE,OAAO,IAAI,MAAM,CAAC;CACnB;AAED,+FAA+F;AAC/F,MAAM,WAAW,YAAY;IAC3B,8FAA8F;IAC9F,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,YAAY,CAEjF"}