signet-auth 1.0.0-beta.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 (152) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +393 -0
  3. package/bin/sig.js +65 -0
  4. package/dist/auth-manager.d.ts +90 -0
  5. package/dist/auth-manager.js +262 -0
  6. package/dist/browser/adapters/playwright.adapter.d.ts +14 -0
  7. package/dist/browser/adapters/playwright.adapter.js +188 -0
  8. package/dist/browser/flows/form-login.flow.d.ts +6 -0
  9. package/dist/browser/flows/form-login.flow.js +35 -0
  10. package/dist/browser/flows/header-capture.d.ts +23 -0
  11. package/dist/browser/flows/header-capture.js +104 -0
  12. package/dist/browser/flows/hybrid-flow.d.ts +37 -0
  13. package/dist/browser/flows/hybrid-flow.js +104 -0
  14. package/dist/browser/flows/oauth-consent.flow.d.ts +20 -0
  15. package/dist/browser/flows/oauth-consent.flow.js +170 -0
  16. package/dist/cli/commands/doctor.d.ts +6 -0
  17. package/dist/cli/commands/doctor.js +263 -0
  18. package/dist/cli/commands/get.d.ts +2 -0
  19. package/dist/cli/commands/get.js +83 -0
  20. package/dist/cli/commands/init.d.ts +6 -0
  21. package/dist/cli/commands/init.js +244 -0
  22. package/dist/cli/commands/login.d.ts +2 -0
  23. package/dist/cli/commands/login.js +77 -0
  24. package/dist/cli/commands/logout.d.ts +2 -0
  25. package/dist/cli/commands/logout.js +11 -0
  26. package/dist/cli/commands/providers.d.ts +2 -0
  27. package/dist/cli/commands/providers.js +30 -0
  28. package/dist/cli/commands/remote.d.ts +1 -0
  29. package/dist/cli/commands/remote.js +67 -0
  30. package/dist/cli/commands/request.d.ts +2 -0
  31. package/dist/cli/commands/request.js +82 -0
  32. package/dist/cli/commands/status.d.ts +2 -0
  33. package/dist/cli/commands/status.js +41 -0
  34. package/dist/cli/commands/sync.d.ts +2 -0
  35. package/dist/cli/commands/sync.js +62 -0
  36. package/dist/cli/formatters.d.ts +3 -0
  37. package/dist/cli/formatters.js +25 -0
  38. package/dist/cli/main.d.ts +8 -0
  39. package/dist/cli/main.js +125 -0
  40. package/dist/config/generator.d.ts +24 -0
  41. package/dist/config/generator.js +97 -0
  42. package/dist/config/loader.d.ts +21 -0
  43. package/dist/config/loader.js +54 -0
  44. package/dist/config/schema.d.ts +44 -0
  45. package/dist/config/schema.js +8 -0
  46. package/dist/config/validator.d.ts +15 -0
  47. package/dist/config/validator.js +228 -0
  48. package/dist/core/errors.d.ts +57 -0
  49. package/dist/core/errors.js +107 -0
  50. package/dist/core/interfaces/auth-strategy.d.ts +48 -0
  51. package/dist/core/interfaces/auth-strategy.js +1 -0
  52. package/dist/core/interfaces/browser-adapter.d.ts +73 -0
  53. package/dist/core/interfaces/browser-adapter.js +1 -0
  54. package/dist/core/interfaces/provider.d.ts +15 -0
  55. package/dist/core/interfaces/provider.js +1 -0
  56. package/dist/core/interfaces/storage.d.ts +21 -0
  57. package/dist/core/interfaces/storage.js +1 -0
  58. package/dist/core/result.d.ts +21 -0
  59. package/dist/core/result.js +16 -0
  60. package/dist/core/types.d.ts +128 -0
  61. package/dist/core/types.js +6 -0
  62. package/dist/deps.d.ts +20 -0
  63. package/dist/deps.js +54 -0
  64. package/dist/index.d.ts +35 -0
  65. package/dist/index.js +37 -0
  66. package/dist/providers/auto-provision.d.ts +9 -0
  67. package/dist/providers/auto-provision.js +27 -0
  68. package/dist/providers/config-loader.d.ts +7 -0
  69. package/dist/providers/config-loader.js +7 -0
  70. package/dist/providers/provider-registry.d.ts +19 -0
  71. package/dist/providers/provider-registry.js +68 -0
  72. package/dist/storage/cached-storage.d.ts +24 -0
  73. package/dist/storage/cached-storage.js +57 -0
  74. package/dist/storage/directory-storage.d.ts +25 -0
  75. package/dist/storage/directory-storage.js +184 -0
  76. package/dist/storage/memory-storage.d.ts +14 -0
  77. package/dist/storage/memory-storage.js +27 -0
  78. package/dist/strategies/api-token.strategy.d.ts +6 -0
  79. package/dist/strategies/api-token.strategy.js +63 -0
  80. package/dist/strategies/basic-auth.strategy.d.ts +6 -0
  81. package/dist/strategies/basic-auth.strategy.js +41 -0
  82. package/dist/strategies/cookie.strategy.d.ts +6 -0
  83. package/dist/strategies/cookie.strategy.js +118 -0
  84. package/dist/strategies/oauth2.strategy.d.ts +6 -0
  85. package/dist/strategies/oauth2.strategy.js +134 -0
  86. package/dist/strategies/registry.d.ts +13 -0
  87. package/dist/strategies/registry.js +25 -0
  88. package/dist/sync/remote-config.d.ts +8 -0
  89. package/dist/sync/remote-config.js +49 -0
  90. package/dist/sync/sync-engine.d.ts +10 -0
  91. package/dist/sync/sync-engine.js +96 -0
  92. package/dist/sync/transports/ssh.d.ts +18 -0
  93. package/dist/sync/transports/ssh.js +115 -0
  94. package/dist/sync/types.d.ts +17 -0
  95. package/dist/sync/types.js +1 -0
  96. package/dist/utils/duration.d.ts +9 -0
  97. package/dist/utils/duration.js +34 -0
  98. package/dist/utils/http.d.ts +4 -0
  99. package/dist/utils/http.js +10 -0
  100. package/dist/utils/jwt.d.ts +15 -0
  101. package/dist/utils/jwt.js +30 -0
  102. package/package.json +56 -0
  103. package/src/auth-manager.ts +331 -0
  104. package/src/browser/adapters/playwright.adapter.ts +247 -0
  105. package/src/browser/flows/form-login.flow.ts +35 -0
  106. package/src/browser/flows/header-capture.ts +128 -0
  107. package/src/browser/flows/hybrid-flow.ts +165 -0
  108. package/src/browser/flows/oauth-consent.flow.ts +200 -0
  109. package/src/cli/commands/doctor.ts +301 -0
  110. package/src/cli/commands/get.ts +96 -0
  111. package/src/cli/commands/init.ts +289 -0
  112. package/src/cli/commands/login.ts +94 -0
  113. package/src/cli/commands/logout.ts +17 -0
  114. package/src/cli/commands/providers.ts +39 -0
  115. package/src/cli/commands/remote.ts +71 -0
  116. package/src/cli/commands/request.ts +97 -0
  117. package/src/cli/commands/status.ts +48 -0
  118. package/src/cli/commands/sync.ts +71 -0
  119. package/src/cli/formatters.ts +31 -0
  120. package/src/cli/main.ts +144 -0
  121. package/src/config/generator.ts +122 -0
  122. package/src/config/loader.ts +70 -0
  123. package/src/config/schema.ts +75 -0
  124. package/src/config/validator.ts +281 -0
  125. package/src/core/errors.ts +182 -0
  126. package/src/core/interfaces/auth-strategy.ts +65 -0
  127. package/src/core/interfaces/browser-adapter.ts +81 -0
  128. package/src/core/interfaces/provider.ts +19 -0
  129. package/src/core/interfaces/storage.ts +26 -0
  130. package/src/core/result.ts +24 -0
  131. package/src/core/types.ts +194 -0
  132. package/src/deps.ts +80 -0
  133. package/src/index.ts +109 -0
  134. package/src/providers/auto-provision.ts +30 -0
  135. package/src/providers/config-loader.ts +8 -0
  136. package/src/providers/provider-registry.ts +79 -0
  137. package/src/storage/cached-storage.ts +72 -0
  138. package/src/storage/directory-storage.ts +204 -0
  139. package/src/storage/memory-storage.ts +35 -0
  140. package/src/strategies/api-token.strategy.ts +87 -0
  141. package/src/strategies/basic-auth.strategy.ts +64 -0
  142. package/src/strategies/cookie.strategy.ts +153 -0
  143. package/src/strategies/oauth2.strategy.ts +178 -0
  144. package/src/strategies/registry.ts +34 -0
  145. package/src/sync/remote-config.ts +60 -0
  146. package/src/sync/sync-engine.ts +113 -0
  147. package/src/sync/transports/ssh.ts +130 -0
  148. package/src/sync/types.ts +15 -0
  149. package/src/utils/duration.ts +34 -0
  150. package/src/utils/http.ts +11 -0
  151. package/src/utils/jwt.ts +39 -0
  152. package/tsconfig.json +20 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pylon Peng
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,393 @@
1
+ # Signet
2
+
3
+ General-purpose authentication CLI. Manages credentials for any web service -- authenticate via browser SSO, store tokens, and make authenticated requests.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g signet-auth
9
+ sig init
10
+ ```
11
+
12
+ That's it. `sig init` auto-detects your browser and creates `~/.signet/config.yaml` with sensible defaults.
13
+
14
+ ### From source
15
+
16
+ ```bash
17
+ git clone <repo-url> && cd signet
18
+ npm install
19
+ npm run build
20
+ ```
21
+
22
+ The CLI is available as `sig` (or `./bin/sig.js`).
23
+
24
+ ## Quick Start
25
+
26
+ ```bash
27
+ sig init # Create config (interactive)
28
+ sig login https://jira.example.com # Authenticate via browser SSO
29
+ sig get jira # Get credentials for scripts/tools
30
+ sig request https://jira.example.com/rest/api/2/myself # Authenticated request
31
+ sig doctor # Check your setup
32
+ ```
33
+
34
+ ## Commands
35
+
36
+ ### `init` -- Set up Signet
37
+
38
+ ```bash
39
+ sig init # Interactive setup (detects browser, offers provider templates)
40
+ sig init --yes # Accept all defaults (non-interactive)
41
+ sig init --force # Overwrite existing config
42
+ sig init --channel msedge --yes # Use Edge instead of Chrome
43
+ ```
44
+
45
+ Creates `~/.signet/config.yaml`, `~/.signet/credentials/`, and `~/.signet/browser-data/`. Detects your installed browser and generates a commented config file.
46
+
47
+ ### `doctor` -- Check your setup
48
+
49
+ ```bash
50
+ sig doctor
51
+ ```
52
+
53
+ Validates your environment: config file, directories, browser availability, Node.js version, stored credentials.
54
+
55
+ ```
56
+ ✓ Config file exists (~/.signet/config.yaml)
57
+ ✓ Config is valid
58
+ ✓ Credentials directory exists (~/.signet/credentials)
59
+ ✓ Browser data directory exists (~/.signet/browser-data)
60
+ ✓ Browser available (chrome)
61
+ ✓ Node.js version (v22.16.0)
62
+ ✓ Stored credentials (2 stored credentials)
63
+
64
+ All checks passed.
65
+ ```
66
+
67
+ ### `login` -- Authenticate with a service
68
+
69
+ ```bash
70
+ sig login <url>
71
+ sig login <url> --token <value>
72
+ sig login <url> --username <user> --password <pass>
73
+ sig login <url> --strategy <cookie|oauth2|api-token|basic>
74
+ ```
75
+
76
+ Opens a browser for SSO login by default. Use `--token` to store an API key or `--username`/`--password` for basic auth without a browser.
77
+
78
+ ### `get` -- Retrieve credentials
79
+
80
+ ```bash
81
+ sig get <provider|url>
82
+ sig get <provider|url> --format json|header|value
83
+ ```
84
+
85
+ Returns stored credentials as JSON (default), raw headers, or just the value.
86
+
87
+ ### `request` -- Make authenticated HTTP requests
88
+
89
+ ```bash
90
+ sig request <url>
91
+ sig request <url> --method POST --body '{"key":"value"}'
92
+ sig request <url> --header "X-Custom: value" --format body
93
+ ```
94
+
95
+ Injects credentials automatically. Supports `GET`, `POST`, `PUT`, `PATCH`. Output as full JSON response (default), body only, or headers only.
96
+
97
+ ### `status` -- Check authentication status
98
+
99
+ ```bash
100
+ sig status
101
+ sig status <provider>
102
+ sig status --format json|table
103
+ ```
104
+
105
+ Shows which providers are authenticated, credential types, and expiry.
106
+
107
+ ### `logout` -- Clear credentials
108
+
109
+ ```bash
110
+ sig logout [provider]
111
+ ```
112
+
113
+ Clears credentials for a specific provider, or all providers if none specified.
114
+
115
+ ### `providers` -- List configured providers
116
+
117
+ ```bash
118
+ sig providers
119
+ sig providers --format json|table
120
+ ```
121
+
122
+ ### `remote` -- Manage remote credential stores
123
+
124
+ ```bash
125
+ sig remote add <name> <host> [--user <user>] [--path <path>] [--ssh-key <key>]
126
+ sig remote remove <name>
127
+ sig remote list
128
+ ```
129
+
130
+ Configure SSH remotes for credential synchronization.
131
+
132
+ ### `sync` -- Sync credentials with remotes
133
+
134
+ ```bash
135
+ sig sync push [remote] [--provider <id>] [--force]
136
+ sig sync pull [remote] [--provider <id>] [--force]
137
+ ```
138
+
139
+ Push or pull credentials to/from remote machines over SSH. Use `--force` to overwrite on conflict.
140
+
141
+ ## Configuration
142
+
143
+ All configuration lives in a single file: `~/.signet/config.yaml`. No env vars, no cascading, no project-local overrides.
144
+
145
+ Run `sig init` to generate a config interactively, or copy `config/config.example.yaml` to `~/.signet/config.yaml`.
146
+
147
+ ### `browser` (required)
148
+
149
+ Controls the browser used for SSO authentication.
150
+
151
+ | Field | Required | Default | Description |
152
+ |-------|----------|---------|-------------|
153
+ | `browserDataDir` | **yes** | -- | Directory for persistent browser profile (cookies, localStorage). Example: `~/.signet/browser-data` |
154
+ | `channel` | **yes** | -- | Browser channel. Values: `chrome`, `msedge`, `chromium` |
155
+ | `headlessTimeout` | **yes** | -- | Timeout in ms for headless auth attempt. Headless is tried first; if it times out, falls back to visible mode. Recommended: `15000`-`30000` |
156
+ | `visibleTimeout` | **yes** | -- | Timeout in ms for visible (user-assisted) auth. Must be long enough for the user to complete SSO manually. Recommended: `60000`-`120000` |
157
+ | `waitUntil` | **yes** | -- | Page load condition before checking auth status. Values: `load` (DOM loaded), `networkidle` (no network activity for 500ms), `domcontentloaded` (HTML parsed), `commit` (first byte received) |
158
+
159
+ ```yaml
160
+ browser:
161
+ browserDataDir: ~/.signet/browser-data
162
+ channel: chrome
163
+ headlessTimeout: 15000
164
+ visibleTimeout: 60000
165
+ waitUntil: load
166
+ ```
167
+
168
+ ### `storage` (required)
169
+
170
+ Where credentials are stored on disk.
171
+
172
+ | Field | Required | Description |
173
+ |-------|----------|-------------|
174
+ | `credentialsDir` | **yes** | Directory for per-provider credential JSON files. Example: `~/.signet/credentials` |
175
+
176
+ ```yaml
177
+ storage:
178
+ credentialsDir: ~/.signet/credentials
179
+ ```
180
+
181
+ ### `remotes` (optional)
182
+
183
+ SSH remotes for syncing credentials to other machines.
184
+
185
+ | Field | Required | Description |
186
+ |-------|----------|-------------|
187
+ | `type` | **yes** | Transport type. Only `ssh` is supported |
188
+ | `host` | **yes** | Remote hostname or IP |
189
+ | `user` | no | SSH username. Defaults to current user |
190
+ | `path` | no | Remote credentials directory. Defaults to `~/.signet/credentials` |
191
+ | `sshKey` | no | Path to SSH private key. Defaults to system SSH config |
192
+
193
+ ```yaml
194
+ remotes:
195
+ dev-server:
196
+ type: ssh
197
+ host: dev.example.com
198
+ user: deploy
199
+ ```
200
+
201
+ ### `providers` (optional)
202
+
203
+ Provider entries map domains to authentication strategies. The key is the provider ID.
204
+
205
+ Most services work with zero config -- just run `sig login <url>` and it auto-provisions a cookie provider. Define providers explicitly for OAuth2, API tokens, or when you need custom settings.
206
+
207
+ #### Common provider fields
208
+
209
+ | Field | Required | Description |
210
+ |-------|----------|-------------|
211
+ | `domains` | **yes** | Array of domains this provider handles. Used for URL-to-provider resolution. Example: `["jira.example.com"]` |
212
+ | `strategy` | **yes** | Authentication strategy. Values: `cookie`, `oauth2`, `api-token`, `basic` |
213
+ | `name` | no | Display name. Defaults to the provider ID |
214
+ | `entryUrl` | no | URL to navigate to for browser-based auth. Required for `cookie` and `oauth2` strategies |
215
+ | `forceVisible` | no | `true` to skip headless attempt and open visible browser immediately. Use for sites requiring CAPTCHAs, QR codes, or interactive auth. Default: `false` |
216
+ | `config` | no | Strategy-specific settings (see below) |
217
+ | `xHeaders` | no | Extra HTTP headers to capture during browser auth (see [xHeaders](#xheaders)) |
218
+
219
+ #### Strategy: `cookie`
220
+
221
+ For SSO-protected web apps. Opens a browser, waits for login, extracts cookies. This is the default strategy -- most sites need no config at all.
222
+
223
+ | Config field | Required | Default | Description |
224
+ |--------------|----------|---------|-------------|
225
+ | `ttl` | no | `24h` | How long cookies are considered valid before re-authentication. Duration string: `ms`, `s`, `m`, `h`, `d`. Examples: `30m`, `12h`, `7d` |
226
+ | `requiredCookies` | no | -- | Cookie names that must exist before auth is considered complete. Use for sites where the entry page isn't a login page (e.g. QR code login). Example: `["session_id", "id_token"]` |
227
+
228
+ ```yaml
229
+ providers:
230
+ jira:
231
+ domains: ["jira.example.com"]
232
+ strategy: cookie
233
+ config:
234
+ ttl: "10d"
235
+ ```
236
+
237
+ Minimal (uses all defaults):
238
+ ```yaml
239
+ providers:
240
+ jira:
241
+ domains: ["jira.example.com"]
242
+ strategy: cookie
243
+ ```
244
+
245
+ #### Strategy: `oauth2`
246
+
247
+ For APIs using OAuth2/JWT tokens. Opens a browser for the OAuth consent flow, extracts tokens from browser localStorage.
248
+
249
+ | Config field | Required | Default | Description |
250
+ |--------------|----------|---------|-------------|
251
+ | `audiences` | no | -- | Filter tokens by audience claim. Only tokens matching these audiences are extracted. Example: `["https://graph.microsoft.com"]` |
252
+ | `tokenEndpoint` | no | -- | Token endpoint URL for refresh_token grant. Required if you want automatic token refresh |
253
+ | `clientId` | no | -- | OAuth2 client ID for refresh_token grant. Required with `tokenEndpoint` |
254
+ | `scopes` | no | -- | OAuth2 scopes for refresh_token grant. Example: `["openid", "profile", "User.Read"]` |
255
+
256
+ ```yaml
257
+ providers:
258
+ ms-teams:
259
+ name: Microsoft Teams
260
+ domains: ["teams.cloud.microsoft"]
261
+ entryUrl: https://teams.cloud.microsoft/v2/
262
+ strategy: oauth2
263
+ config:
264
+ audiences: ["https://ic3.teams.office.com"]
265
+ ```
266
+
267
+ #### Strategy: `api-token`
268
+
269
+ For static API keys or personal access tokens. No browser needed -- prompts the user to enter a token.
270
+
271
+ | Config field | Required | Default | Description |
272
+ |--------------|----------|---------|-------------|
273
+ | `headerName` | no | `Authorization` | HTTP header name to place the token in |
274
+ | `headerPrefix` | no | `Bearer` | Prefix before the token value. Set to empty string for no prefix |
275
+ | `setupInstructions` | no | -- | Instructions shown to the user when a token is needed. Supports multi-line |
276
+
277
+ ```yaml
278
+ providers:
279
+ github:
280
+ name: GitHub
281
+ domains: ["github.com", "api.github.com"]
282
+ strategy: api-token
283
+ config:
284
+ headerName: Authorization
285
+ headerPrefix: Bearer
286
+ setupInstructions: |
287
+ Create a Personal Access Token at:
288
+ https://github.com/settings/tokens
289
+ ```
290
+
291
+ #### Strategy: `basic`
292
+
293
+ For username/password authentication. No browser needed -- prompts the user for credentials.
294
+
295
+ | Config field | Required | Default | Description |
296
+ |--------------|----------|---------|-------------|
297
+ | `setupInstructions` | no | -- | Instructions shown to the user when credentials are needed |
298
+
299
+ ```yaml
300
+ providers:
301
+ legacy-api:
302
+ domains: ["api.internal.corp"]
303
+ strategy: basic
304
+ config:
305
+ setupInstructions: "Contact IT for credentials."
306
+ ```
307
+
308
+ #### xHeaders
309
+
310
+ Capture extra HTTP headers during browser authentication. Useful for APIs that require anti-bot signatures, CSRF tokens, or custom headers that are set dynamically by the web app.
311
+
312
+ Captured headers are stored alongside the credential and applied automatically on `sig get` and `sig request`.
313
+
314
+ | Field | Required | Description |
315
+ |-------|----------|-------------|
316
+ | `name` | **yes** | HTTP header name to capture (case-insensitive match) |
317
+ | `source` | no | Where to capture from: `request` or `response`. Default: both |
318
+ | `urlPattern` | no | Only capture from URLs matching this substring |
319
+ | `staticValue` | no | Use a fixed value instead of capturing dynamically. When set, `source` and `urlPattern` are ignored |
320
+
321
+ ```yaml
322
+ providers:
323
+ my-app:
324
+ domains: ["app.example.com"]
325
+ entryUrl: https://app.example.com/
326
+ strategy: cookie
327
+ forceVisible: true
328
+ config:
329
+ requiredCookies: ["id_token"]
330
+ xHeaders:
331
+ - name: x-csrf-token
332
+ source: request
333
+ urlPattern: app.example.com/api
334
+ - name: origin
335
+ staticValue: https://app.example.com
336
+ - name: referer
337
+ staticValue: https://app.example.com/
338
+ ```
339
+
340
+ ### Full example
341
+
342
+ ```yaml
343
+ browser:
344
+ browserDataDir: ~/.signet/browser-data
345
+ channel: chrome
346
+ headlessTimeout: 15000
347
+ visibleTimeout: 60000
348
+ waitUntil: load
349
+
350
+ storage:
351
+ credentialsDir: ~/.signet/credentials
352
+
353
+ remotes:
354
+ dev-server:
355
+ type: ssh
356
+ host: dev.example.com
357
+ user: deploy
358
+
359
+ providers:
360
+ jira:
361
+ domains: ["jira.example.com"]
362
+ strategy: cookie
363
+ config:
364
+ ttl: "10d"
365
+
366
+ github:
367
+ domains: ["github.com", "api.github.com"]
368
+ strategy: api-token
369
+ config:
370
+ setupInstructions: "Create a PAT at https://github.com/settings/tokens"
371
+
372
+ ms-teams:
373
+ domains: ["teams.cloud.microsoft"]
374
+ entryUrl: https://teams.cloud.microsoft/v2/
375
+ strategy: oauth2
376
+ config:
377
+ audiences: ["https://ic3.teams.office.com"]
378
+ ```
379
+
380
+ ## Authentication Strategies
381
+
382
+ | Strategy | When to use | Browser needed |
383
+ |----------|-------------|----------------|
384
+ | **cookie** | SSO-protected web apps (default) | Yes |
385
+ | **oauth2** | APIs with OAuth2/JWT tokens | Yes |
386
+ | **api-token** | Static API keys or PATs | No |
387
+ | **basic** | Username/password auth | No |
388
+
389
+ Cookie-based auth is the default -- just `sig login <url>` and complete SSO in the browser window.
390
+
391
+ ## License
392
+
393
+ [MIT](LICENSE)
package/bin/sig.js ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync, existsSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, join } from 'node:path';
6
+ import { execSync } from 'node:child_process';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const rootDir = join(__dirname, '..');
11
+
12
+ function getVersion() {
13
+ try {
14
+ const pkg = JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf-8'));
15
+ return pkg.version || 'unknown';
16
+ } catch {
17
+ return 'unknown';
18
+ }
19
+ }
20
+
21
+ function buildIfNeeded() {
22
+ const distPath = join(rootDir, 'dist', 'index.js');
23
+ if (!existsSync(distPath)) {
24
+ // If no .git directory, this is likely a global install with missing dist/
25
+ const gitDir = join(rootDir, '.git');
26
+ if (!existsSync(gitDir)) {
27
+ console.error('[signet] dist/ directory is missing and this is not a dev checkout.');
28
+ console.error('[signet] Please reinstall: npm install -g signet-auth');
29
+ process.exit(1);
30
+ }
31
+
32
+ // Dev checkout: build from source
33
+ console.error('[signet] Building project...');
34
+ try {
35
+ execSync('npm run build', { cwd: rootDir, stdio: 'inherit' });
36
+ } catch (e) {
37
+ console.error('[signet] Build failed:', e.message);
38
+ process.exit(1);
39
+ }
40
+ }
41
+ }
42
+
43
+ async function main() {
44
+ const args = process.argv.slice(2);
45
+
46
+ if (args.includes('--version') || args.includes('-v')) {
47
+ console.log(getVersion());
48
+ process.exit(0);
49
+ }
50
+
51
+ buildIfNeeded();
52
+
53
+ const { run } = await import(join(rootDir, 'dist', 'cli', 'main.js'));
54
+ await run(args);
55
+ }
56
+
57
+ // Graceful shutdown
58
+ process.on('SIGINT', () => process.exit(0));
59
+ process.on('SIGTERM', () => process.exit(0));
60
+ process.on('unhandledRejection', (err) => {
61
+ console.error('[signet] Unhandled rejection:', err);
62
+ process.exit(1);
63
+ });
64
+
65
+ main();
@@ -0,0 +1,90 @@
1
+ import type { IBrowserAdapter } from './core/interfaces/browser-adapter.js';
2
+ import type { IStorage } from './core/interfaces/storage.js';
3
+ import type { IProviderRegistry } from './core/interfaces/provider.js';
4
+ import type { Credential, ProviderConfig, ProviderStatus, ILogger } from './core/types.js';
5
+ import type { BrowserConfig } from './config/schema.js';
6
+ import type { Result } from './core/result.js';
7
+ import { type AuthError } from './core/errors.js';
8
+ import { StrategyRegistry } from './strategies/registry.js';
9
+ export interface AuthManagerDeps {
10
+ storage: IStorage;
11
+ strategyRegistry: StrategyRegistry;
12
+ providerRegistry: IProviderRegistry;
13
+ browserAdapterFactory: () => IBrowserAdapter;
14
+ browserConfig: BrowserConfig;
15
+ logger?: ILogger;
16
+ }
17
+ /**
18
+ * Central orchestrator for authentication lifecycle.
19
+ * All dependencies are injected — no singletons, no global state.
20
+ *
21
+ * Flow: validate → refresh → authenticate
22
+ */
23
+ export declare class AuthManager {
24
+ private readonly storage;
25
+ private readonly strategies;
26
+ private readonly providers;
27
+ private readonly browserAdapterFactory;
28
+ private readonly browserConfig;
29
+ private readonly logger?;
30
+ constructor(deps: AuthManagerDeps);
31
+ /**
32
+ * Get valid credentials for a provider.
33
+ * Tries: stored → refresh → authenticate, in that order.
34
+ */
35
+ getCredentials(providerId: string): Promise<Result<Credential, AuthError>>;
36
+ /**
37
+ * Resolve a provider by URL, auto-provisioning a default cookie provider if none matches.
38
+ */
39
+ resolveProvider(url: string): ProviderConfig;
40
+ /**
41
+ * Get credentials for a specific provider, resolving by URL.
42
+ */
43
+ getCredentialsByUrl(url: string): Promise<Result<{
44
+ provider: ProviderConfig;
45
+ credential: Credential;
46
+ }, AuthError>>;
47
+ /**
48
+ * Force re-authentication, deleting any stored credentials first.
49
+ */
50
+ forceReauth(providerId: string): Promise<Result<Credential, AuthError>>;
51
+ /**
52
+ * Store a credential directly (e.g., user-provided API token).
53
+ */
54
+ setCredential(providerId: string, credential: Credential): Promise<Result<void, AuthError>>;
55
+ /**
56
+ * Get status for a provider (non-triggering — won't start auth).
57
+ */
58
+ getStatus(providerId: string): Promise<ProviderStatus>;
59
+ /**
60
+ * Get status for all configured providers.
61
+ */
62
+ getAllStatus(): Promise<ProviderStatus[]>;
63
+ /**
64
+ * Clear stored credentials for a provider.
65
+ */
66
+ clearCredentials(providerId: string): Promise<void>;
67
+ /**
68
+ * Clear all stored credentials.
69
+ */
70
+ clearAll(): Promise<void>;
71
+ /**
72
+ * Apply credentials to an outgoing request (as headers).
73
+ */
74
+ applyToRequest(providerId: string, credential: Credential): Record<string, string>;
75
+ /**
76
+ * Validate a credential by making a test request to the provider's entry URL.
77
+ * Returns the HTTP status and whether the response redirects to a login page.
78
+ */
79
+ validateCredential(provider: ProviderConfig, credential: Credential): Promise<{
80
+ status: number | null;
81
+ isLoginRedirect: boolean;
82
+ }>;
83
+ /** Expose the provider registry for handlers */
84
+ get providerRegistry(): IProviderRegistry;
85
+ /** Storage key: uses credentialFile if configured, otherwise provider ID. */
86
+ private storageKey;
87
+ private checkCredentialType;
88
+ private store;
89
+ private getExpiresAt;
90
+ }