signet-auth 1.1.1 → 1.2.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.
package/README.md CHANGED
@@ -298,9 +298,12 @@ providers:
298
298
  config:
299
299
  audiences: ['https://ic3.teams.office.com']
300
300
 
301
+ # IMPORTANT: entryUrl must point to a specific workspace (/client/<TEAM_ID>),
302
+ # not the root URL, which shows a workspace picker where localStorage
303
+ # is not yet populated.
301
304
  slack:
302
305
  domains: ['app.slack.com', 'edgeapi.slack.com']
303
- entryUrl: https://app.slack.com/
306
+ entryUrl: https://app.slack.com/client/<TEAM_ID>
304
307
  strategy: cookie
305
308
  config:
306
309
  ttl: '7d'
@@ -308,7 +311,7 @@ providers:
308
311
  localStorage:
309
312
  - name: token
310
313
  key: localConfig_v2
311
- jsonPath: teams.*.token
314
+ jsonPath: teams.<TEAM_ID>.token
312
315
  ```
313
316
 
314
317
  ## Strategies
@@ -380,17 +383,19 @@ Extract values from browser localStorage after authentication. Useful for apps t
380
383
 
381
384
  Extracted values are stored on the credential and included in `sig get` JSON output, but are NOT applied as HTTP headers.
382
385
 
383
- | Field | Required | Description |
384
- | ---------- | -------- | ---------------------------------------------------------------- |
385
- | `name` | **yes** | Output key name for the extracted value |
386
- | `key` | **yes** | localStorage key to read |
387
- | `jsonPath` | no | Dot-delimited path into parsed JSON value (e.g. `teams.*.token`) |
386
+ **Important:** The `entryUrl` must point to a page where localStorage is actually populated. For example, Slack's root URL shows a workspace picker — localStorage is only populated after entering a workspace. Use a direct workspace URL like `https://app.slack.com/client/<TEAM_ID>` instead.
387
+
388
+ | Field | Required | Description |
389
+ | ---------- | -------- | ------------------------------------------------------------------------ |
390
+ | `name` | **yes** | Output key name for the extracted value |
391
+ | `key` | **yes** | localStorage key to read |
392
+ | `jsonPath` | no | Dot-delimited path into parsed JSON value (e.g. `teams.<TEAM_ID>.token`) |
388
393
 
389
394
  ```yaml
390
395
  localStorage:
391
396
  - name: token
392
397
  key: localConfig_v2
393
- jsonPath: teams.*.token
398
+ jsonPath: teams.<TEAM_ID>.token
394
399
  ```
395
400
 
396
401
  ## Remote / Headless Setup
@@ -1,25 +1,4 @@
1
- /**
2
- * Resolve a dot-delimited JSON path on an object.
3
- * Numeric segments index into arrays (e.g. "teams.0.token").
4
- * Returns undefined if any segment is missing.
5
- */
6
- function resolveJsonPath(obj, path) {
7
- let current = obj;
8
- for (const segment of path.split('.')) {
9
- if (current == null || typeof current !== 'object')
10
- return undefined;
11
- if (Array.isArray(current)) {
12
- const index = Number(segment);
13
- if (!Number.isInteger(index) || index < 0)
14
- return undefined;
15
- current = current[index];
16
- }
17
- else {
18
- current = current[segment];
19
- }
20
- }
21
- return current;
22
- }
1
+ import dlv from 'dlv';
23
2
  /**
24
3
  * Extract values from the browser's localStorage.
25
4
  *
@@ -43,7 +22,7 @@ export async function extractLocalStorage(page, configs) {
43
22
  if (config.jsonPath) {
44
23
  try {
45
24
  const parsed = JSON.parse(raw);
46
- const value = resolveJsonPath(parsed, config.jsonPath);
25
+ const value = dlv(parsed, config.jsonPath);
47
26
  if (typeof value === 'string') {
48
27
  result[config.name] = value;
49
28
  }
@@ -1,7 +1,17 @@
1
1
  import { isOk } from '../../core/result.js';
2
2
  import { formatJson, formatCredentialHeaders } from '../formatters.js';
3
3
  import { ExitCode } from '../exit-codes.js';
4
- const PRIMARY_HEADERS = ['cookie', 'authorization'];
4
+ import { CredentialTypeName, HttpHeader, OutputFormat } from '../../core/constants.js';
5
+ const PRIMARY_HEADERS = [HttpHeader.COOKIE.toLowerCase(), HttpHeader.AUTHORIZATION.toLowerCase()];
6
+ function getLocalStorage(credential) {
7
+ if (credential.type === CredentialTypeName.COOKIE ||
8
+ credential.type === CredentialTypeName.BEARER) {
9
+ const ls = credential.localStorage;
10
+ if (ls && Object.keys(ls).length > 0)
11
+ return ls;
12
+ }
13
+ return undefined;
14
+ }
5
15
  export async function runGet(positionals, flags, deps) {
6
16
  const target = positionals[0];
7
17
  if (!target) {
@@ -67,39 +77,39 @@ export async function runGet(positionals, flags, deps) {
67
77
  xHeaders[name] = value;
68
78
  }
69
79
  }
70
- const format = flags.format ?? 'json';
80
+ const format = flags.format ?? OutputFormat.JSON;
71
81
  switch (format) {
72
- case 'json': {
73
- const output = {
74
- provider: providerId,
75
- credential: primaryHeaderValue,
76
- headerName: primaryHeaderName,
82
+ case OutputFormat.JSON: {
83
+ const credentialObj = {
77
84
  type: credential.type,
85
+ headerName: primaryHeaderName,
86
+ value: primaryHeaderValue,
78
87
  };
79
88
  if (Object.keys(xHeaders).length > 0)
80
- output.xHeaders = xHeaders;
81
- if (credential.type === 'cookie' || credential.type === 'bearer') {
82
- if (credential.localStorage && Object.keys(credential.localStorage).length > 0) {
83
- output.localStorage = credential.localStorage;
84
- }
85
- }
89
+ credentialObj.xHeaders = xHeaders;
90
+ const ls = getLocalStorage(credential);
91
+ if (ls)
92
+ credentialObj.localStorage = ls;
93
+ const output = {
94
+ provider: providerId,
95
+ credential: credentialObj,
96
+ };
86
97
  process.stdout.write(formatJson(output) + '\n');
87
98
  break;
88
99
  }
89
- case 'header': {
100
+ case OutputFormat.HEADER: {
90
101
  process.stdout.write(formatCredentialHeaders(headers) + '\n');
91
102
  break;
92
103
  }
93
- case 'value': {
104
+ case OutputFormat.VALUE: {
94
105
  process.stdout.write(primaryHeaderValue + '\n');
95
106
  for (const [name, value] of Object.entries(xHeaders)) {
96
107
  process.stdout.write(`${name}=${value}\n`);
97
108
  }
98
- if (credential.type === 'cookie' || credential.type === 'bearer') {
99
- if (credential.localStorage && Object.keys(credential.localStorage).length > 0) {
100
- for (const [name, value] of Object.entries(credential.localStorage)) {
101
- process.stdout.write(`${name}=${value}\n`);
102
- }
109
+ const ls = getLocalStorage(credential);
110
+ if (ls) {
111
+ for (const [name, value] of Object.entries(ls)) {
112
+ process.stdout.write(`${name}=${value}\n`);
103
113
  }
104
114
  }
105
115
  break;
@@ -98,6 +98,15 @@ export declare const AuthScheme: {
98
98
  readonly BEARER: "Bearer";
99
99
  readonly BASIC: "Basic";
100
100
  };
101
+ /**
102
+ * Output format options for `sig get`.
103
+ */
104
+ export declare const OutputFormat: {
105
+ readonly JSON: "json";
106
+ readonly HEADER: "header";
107
+ readonly VALUE: "value";
108
+ };
109
+ export type OutputFormatValue = (typeof OutputFormat)[keyof typeof OutputFormat];
101
110
  /**
102
111
  * Application identity.
103
112
  */
@@ -112,6 +112,14 @@ export const AuthScheme = {
112
112
  BEARER: 'Bearer',
113
113
  BASIC: 'Basic',
114
114
  };
115
+ /**
116
+ * Output format options for `sig get`.
117
+ */
118
+ export const OutputFormat = {
119
+ JSON: 'json',
120
+ HEADER: 'header',
121
+ VALUE: 'value',
122
+ };
115
123
  /**
116
124
  * Application identity.
117
125
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signet-auth",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "General-purpose authentication CLI with pluggable strategies and browser adapters",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -35,12 +35,14 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "croner": "^10.0.1",
38
+ "dlv": "^1.1.3",
38
39
  "playwright-core": "^1.50.0",
39
40
  "proper-lockfile": "^4.1.2",
40
41
  "yaml": "^2.7.0"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@eslint/js": "^10.0.1",
45
+ "@types/dlv": "^1.1.5",
44
46
  "@types/node": "^20.10.0",
45
47
  "@types/proper-lockfile": "^4.1.4",
46
48
  "eslint": "^10.2.0",