gh-setup-git-identity 0.4.2 → 0.6.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/CHANGELOG.md +36 -0
- package/README.md +116 -8
- package/package.json +1 -1
- package/src/cli.js +138 -4
- package/src/index.js +81 -10
- package/test/index.test.js +35 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# gh-setup-git-identity
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1094f06: feat: fully configurable support of `gh auth login`
|
|
8
|
+
|
|
9
|
+
Added configurable options for GitHub authentication that mirror all `gh auth login` flags:
|
|
10
|
+
|
|
11
|
+
- `--hostname`: GitHub hostname (default: `github.com`) - enables GitHub Enterprise support
|
|
12
|
+
- `--scopes` / `-s`: Authentication scopes (default: `repo,workflow,user,read:org,gist`)
|
|
13
|
+
- `--git-protocol` / `-p`: Git protocol - `ssh` or `https` (default: `https`)
|
|
14
|
+
- `--web` / `-w`: Open browser to authenticate (default: `true`)
|
|
15
|
+
- `--with-token`: Read token from stdin for non-interactive authentication
|
|
16
|
+
- `--skip-ssh-key`: Skip SSH key generation/upload prompt
|
|
17
|
+
- `--insecure-storage`: Store credentials in plain text instead of credential store
|
|
18
|
+
- `--clipboard`: Copy OAuth code to clipboard
|
|
19
|
+
|
|
20
|
+
These options can be configured via:
|
|
21
|
+
|
|
22
|
+
- CLI flags
|
|
23
|
+
- Environment variables (`GH_AUTH_HOSTNAME`, `GH_AUTH_SCOPES`, etc.)
|
|
24
|
+
- `.lenv` configuration file
|
|
25
|
+
|
|
26
|
+
The library also exports `defaultAuthOptions` object with all default values.
|
|
27
|
+
|
|
28
|
+
## 0.5.0
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
31
|
+
|
|
32
|
+
- 071e6d3: feat: add --verify option to verify git identity configuration
|
|
33
|
+
|
|
34
|
+
- Added `--verify` CLI option to run all 3 verification commands at once
|
|
35
|
+
- Users can now use `gh-setup-git-identity --verify` instead of running individual commands
|
|
36
|
+
- Works with `--local` flag for local repository configuration
|
|
37
|
+
- Updated README with verification documentation and code blocks
|
|
38
|
+
|
|
3
39
|
## 0.4.2
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -74,6 +74,9 @@ gh-setup-git-identity --local
|
|
|
74
74
|
# Preview what would be configured (dry run)
|
|
75
75
|
gh-setup-git-identity --dry-run
|
|
76
76
|
|
|
77
|
+
# Verify current git identity configuration
|
|
78
|
+
gh-setup-git-identity --verify
|
|
79
|
+
|
|
77
80
|
# Enable verbose output
|
|
78
81
|
gh-setup-git-identity --verbose
|
|
79
82
|
```
|
|
@@ -83,13 +86,51 @@ gh-setup-git-identity --verbose
|
|
|
83
86
|
```
|
|
84
87
|
Usage: gh-setup-git-identity [options]
|
|
85
88
|
|
|
86
|
-
Options:
|
|
87
|
-
--global, -g
|
|
88
|
-
--local, -l
|
|
89
|
-
--dry-run, --dry
|
|
90
|
-
--
|
|
91
|
-
--
|
|
92
|
-
|
|
89
|
+
Git Identity Options:
|
|
90
|
+
--global, -g Set git config globally (default: true)
|
|
91
|
+
--local, -l Set git config locally (in current repository)
|
|
92
|
+
--dry-run, --dry Dry run - show what would be done without making changes
|
|
93
|
+
--verify Verify current git identity configuration
|
|
94
|
+
--verbose, -v Enable verbose output
|
|
95
|
+
|
|
96
|
+
GitHub Authentication Options:
|
|
97
|
+
--hostname GitHub hostname to authenticate with (default: github.com)
|
|
98
|
+
--scopes, -s Authentication scopes, comma-separated (default: repo,workflow,user,read:org,gist)
|
|
99
|
+
--git-protocol, -p Protocol for git operations: ssh or https (default: https)
|
|
100
|
+
--web, -w Open a browser to authenticate (default: true)
|
|
101
|
+
--with-token Read token from standard input
|
|
102
|
+
--skip-ssh-key Skip generate/upload SSH key prompt
|
|
103
|
+
--insecure-storage Save credentials in plain text instead of credential store
|
|
104
|
+
--clipboard Copy one-time OAuth device code to clipboard
|
|
105
|
+
|
|
106
|
+
General Options:
|
|
107
|
+
--help, -h Show help
|
|
108
|
+
--version Show version number
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Advanced Authentication Examples
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Authenticate with GitHub Enterprise
|
|
115
|
+
gh-setup-git-identity --hostname enterprise.github.com
|
|
116
|
+
|
|
117
|
+
# Use SSH protocol instead of HTTPS
|
|
118
|
+
gh-setup-git-identity --git-protocol ssh
|
|
119
|
+
|
|
120
|
+
# Authenticate with custom scopes
|
|
121
|
+
gh-setup-git-identity --scopes repo,user,gist
|
|
122
|
+
|
|
123
|
+
# Use token-based authentication (reads from stdin)
|
|
124
|
+
echo "ghp_xxxxx" | gh-setup-git-identity --with-token
|
|
125
|
+
|
|
126
|
+
# Copy OAuth code to clipboard automatically
|
|
127
|
+
gh-setup-git-identity --clipboard
|
|
128
|
+
|
|
129
|
+
# Skip SSH key generation prompt
|
|
130
|
+
gh-setup-git-identity --git-protocol ssh --skip-ssh-key
|
|
131
|
+
|
|
132
|
+
# Store credentials in plain text (not recommended for production)
|
|
133
|
+
gh-setup-git-identity --insecure-storage
|
|
93
134
|
```
|
|
94
135
|
|
|
95
136
|
### First Run (Not Authenticated)
|
|
@@ -136,6 +177,36 @@ You can verify your configuration with:
|
|
|
136
177
|
git config --global user.email
|
|
137
178
|
```
|
|
138
179
|
|
|
180
|
+
### Verifying Configuration
|
|
181
|
+
|
|
182
|
+
You can verify your git identity configuration at any time using:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
gh-setup-git-identity --verify
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Or by running the three verification commands directly:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
gh auth status
|
|
192
|
+
git config --global user.name
|
|
193
|
+
git config --global user.email
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
For local repository configuration, use `--local`:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
gh-setup-git-identity --verify --local
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Or:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
gh auth status
|
|
206
|
+
git config --local user.name
|
|
207
|
+
git config --local user.email
|
|
208
|
+
```
|
|
209
|
+
|
|
139
210
|
## Library Usage
|
|
140
211
|
|
|
141
212
|
### Basic Example
|
|
@@ -172,14 +243,39 @@ Check if GitHub CLI is authenticated.
|
|
|
172
243
|
|
|
173
244
|
#### `runGhAuthLogin(options?)`
|
|
174
245
|
|
|
175
|
-
Run `gh auth login`
|
|
246
|
+
Run `gh auth login` with configurable options.
|
|
176
247
|
|
|
177
248
|
**Parameters:**
|
|
249
|
+
- `options.hostname` - GitHub hostname (default: `'github.com'`)
|
|
250
|
+
- `options.scopes` - OAuth scopes, comma-separated (default: `'repo,workflow,user,read:org,gist'`)
|
|
251
|
+
- `options.gitProtocol` - Git protocol: `'ssh'` or `'https'` (default: `'https'`)
|
|
252
|
+
- `options.web` - Open browser to authenticate (default: `true`)
|
|
253
|
+
- `options.withToken` - Read token from stdin (default: `false`)
|
|
254
|
+
- `options.skipSshKey` - Skip SSH key prompt (default: `false`)
|
|
255
|
+
- `options.insecureStorage` - Store credentials in plain text (default: `false`)
|
|
256
|
+
- `options.clipboard` - Copy OAuth code to clipboard (default: `false`)
|
|
178
257
|
- `options.verbose` - Enable verbose logging (default: `false`)
|
|
179
258
|
- `options.logger` - Custom logger (default: `console`)
|
|
180
259
|
|
|
181
260
|
**Returns:** `Promise<boolean>` - `true` if login was successful
|
|
182
261
|
|
|
262
|
+
#### `defaultAuthOptions`
|
|
263
|
+
|
|
264
|
+
Default authentication options object that can be imported and used as a reference:
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
{
|
|
268
|
+
hostname: 'github.com',
|
|
269
|
+
scopes: 'repo,workflow,user,read:org,gist',
|
|
270
|
+
gitProtocol: 'https',
|
|
271
|
+
web: true,
|
|
272
|
+
withToken: false,
|
|
273
|
+
skipSshKey: false,
|
|
274
|
+
insecureStorage: false,
|
|
275
|
+
clipboard: false
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
183
279
|
#### `getGitHubUserInfo(options?)`
|
|
184
280
|
|
|
185
281
|
Get GitHub user information (username and primary email).
|
|
@@ -208,11 +304,23 @@ Get current git identity configuration.
|
|
|
208
304
|
|
|
209
305
|
### Environment Variables
|
|
210
306
|
|
|
307
|
+
#### Git Identity Options
|
|
308
|
+
|
|
211
309
|
- `GH_SETUP_GIT_IDENTITY_GLOBAL` - Set global config (default: `true`)
|
|
212
310
|
- `GH_SETUP_GIT_IDENTITY_LOCAL` - Set local config (default: `false`)
|
|
213
311
|
- `GH_SETUP_GIT_IDENTITY_DRY_RUN` - Enable dry run mode (default: `false`)
|
|
214
312
|
- `GH_SETUP_GIT_IDENTITY_VERBOSE` - Enable verbose output (default: `false`)
|
|
215
313
|
|
|
314
|
+
#### GitHub Authentication Options
|
|
315
|
+
|
|
316
|
+
- `GH_AUTH_HOSTNAME` - GitHub hostname (default: `github.com`)
|
|
317
|
+
- `GH_AUTH_SCOPES` - Authentication scopes (default: `repo,workflow,user,read:org,gist`)
|
|
318
|
+
- `GH_AUTH_GIT_PROTOCOL` - Git protocol: `ssh` or `https` (default: `https`)
|
|
319
|
+
- `GH_AUTH_WEB` - Open browser for authentication (default: `true`)
|
|
320
|
+
- `GH_AUTH_SKIP_SSH_KEY` - Skip SSH key prompt (default: `false`)
|
|
321
|
+
- `GH_AUTH_INSECURE_STORAGE` - Store credentials in plain text (default: `false`)
|
|
322
|
+
- `GH_AUTH_CLIPBOARD` - Copy OAuth code to clipboard (default: `false`)
|
|
323
|
+
|
|
216
324
|
## Testing
|
|
217
325
|
|
|
218
326
|
Run tests using bun:
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { makeConfig } from 'lino-arguments';
|
|
10
|
-
import { setupGitIdentity, isGhAuthenticated, runGhAuthLogin } from './index.js';
|
|
10
|
+
import { setupGitIdentity, isGhAuthenticated, runGhAuthLogin, verifyGitIdentity, defaultAuthOptions } from './index.js';
|
|
11
11
|
|
|
12
12
|
// Parse command-line arguments with environment variable and .lenv support
|
|
13
13
|
const config = makeConfig({
|
|
14
14
|
yargs: ({ yargs, getenv }) =>
|
|
15
15
|
yargs
|
|
16
16
|
.usage('Usage: $0 [options]')
|
|
17
|
+
// Git identity options
|
|
17
18
|
.option('global', {
|
|
18
19
|
alias: 'g',
|
|
19
20
|
type: 'boolean',
|
|
@@ -38,22 +39,136 @@ const config = makeConfig({
|
|
|
38
39
|
description: 'Dry run mode - show what would be done without making changes',
|
|
39
40
|
default: getenv('GH_SETUP_GIT_IDENTITY_DRY_RUN', false)
|
|
40
41
|
})
|
|
42
|
+
.option('verify', {
|
|
43
|
+
type: 'boolean',
|
|
44
|
+
description: 'Verify current git identity configuration',
|
|
45
|
+
default: false
|
|
46
|
+
})
|
|
47
|
+
// gh auth login options
|
|
48
|
+
.option('hostname', {
|
|
49
|
+
type: 'string',
|
|
50
|
+
description: 'GitHub hostname to authenticate with',
|
|
51
|
+
default: getenv('GH_AUTH_HOSTNAME', defaultAuthOptions.hostname)
|
|
52
|
+
})
|
|
53
|
+
.option('scopes', {
|
|
54
|
+
alias: 's',
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Additional authentication scopes to request (comma-separated)',
|
|
57
|
+
default: getenv('GH_AUTH_SCOPES', defaultAuthOptions.scopes)
|
|
58
|
+
})
|
|
59
|
+
.option('git-protocol', {
|
|
60
|
+
alias: 'p',
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'Protocol for git operations: ssh or https',
|
|
63
|
+
choices: ['ssh', 'https'],
|
|
64
|
+
default: getenv('GH_AUTH_GIT_PROTOCOL', defaultAuthOptions.gitProtocol)
|
|
65
|
+
})
|
|
66
|
+
.option('web', {
|
|
67
|
+
alias: 'w',
|
|
68
|
+
type: 'boolean',
|
|
69
|
+
description: 'Open a browser to authenticate',
|
|
70
|
+
default: getenv('GH_AUTH_WEB', defaultAuthOptions.web)
|
|
71
|
+
})
|
|
72
|
+
.option('with-token', {
|
|
73
|
+
type: 'boolean',
|
|
74
|
+
description: 'Read token from standard input',
|
|
75
|
+
default: false
|
|
76
|
+
})
|
|
77
|
+
.option('skip-ssh-key', {
|
|
78
|
+
type: 'boolean',
|
|
79
|
+
description: 'Skip generate/upload SSH key prompt',
|
|
80
|
+
default: getenv('GH_AUTH_SKIP_SSH_KEY', defaultAuthOptions.skipSshKey)
|
|
81
|
+
})
|
|
82
|
+
.option('insecure-storage', {
|
|
83
|
+
type: 'boolean',
|
|
84
|
+
description: 'Save authentication credentials in plain text instead of credential store',
|
|
85
|
+
default: getenv('GH_AUTH_INSECURE_STORAGE', defaultAuthOptions.insecureStorage)
|
|
86
|
+
})
|
|
87
|
+
.option('clipboard', {
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
description: 'Copy one-time OAuth device code to clipboard',
|
|
90
|
+
default: getenv('GH_AUTH_CLIPBOARD', defaultAuthOptions.clipboard)
|
|
91
|
+
})
|
|
41
92
|
.check((argv) => {
|
|
42
93
|
// --global and --local are mutually exclusive
|
|
43
94
|
if (argv.global && argv.local) {
|
|
44
95
|
throw new Error('Arguments global and local are mutually exclusive');
|
|
45
96
|
}
|
|
97
|
+
// --web and --with-token are mutually exclusive
|
|
98
|
+
if (argv.web && argv.withToken) {
|
|
99
|
+
throw new Error('Arguments web and with-token are mutually exclusive');
|
|
100
|
+
}
|
|
46
101
|
return true;
|
|
47
102
|
})
|
|
48
103
|
.example('$0', 'Setup git identity globally using GitHub user')
|
|
49
104
|
.example('$0 --local', 'Setup git identity for current repository only')
|
|
50
105
|
.example('$0 --dry-run', 'Show what would be configured without making changes')
|
|
106
|
+
.example('$0 --verify', 'Verify current git identity configuration')
|
|
107
|
+
.example('$0 --hostname enterprise.github.com', 'Authenticate with GitHub Enterprise')
|
|
108
|
+
.example('$0 --scopes repo,user,gist', 'Authenticate with custom scopes')
|
|
109
|
+
.example('$0 --git-protocol ssh', 'Use SSH protocol for git operations')
|
|
110
|
+
.example('$0 --with-token < token.txt', 'Authenticate using a token file')
|
|
51
111
|
.help('h')
|
|
52
112
|
.alias('h', 'help')
|
|
53
113
|
.version('0.1.0')
|
|
54
114
|
.strict(),
|
|
55
115
|
});
|
|
56
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Run verification commands and display results
|
|
119
|
+
* @param {string} scope - 'global' or 'local'
|
|
120
|
+
* @param {boolean} verbose - Enable verbose logging
|
|
121
|
+
*/
|
|
122
|
+
async function runVerify(scope, verbose) {
|
|
123
|
+
const scopeFlag = scope === 'local' ? '--local' : '--global';
|
|
124
|
+
|
|
125
|
+
console.log('Verifying git identity configuration...');
|
|
126
|
+
console.log('');
|
|
127
|
+
|
|
128
|
+
// 1. Run gh auth status
|
|
129
|
+
console.log('1. GitHub CLI authentication status:');
|
|
130
|
+
console.log(' $ gh auth status');
|
|
131
|
+
console.log('');
|
|
132
|
+
|
|
133
|
+
const { spawn } = await import('node:child_process');
|
|
134
|
+
|
|
135
|
+
// Run gh auth status interactively to show full output
|
|
136
|
+
await new Promise((resolve) => {
|
|
137
|
+
const child = spawn('gh', ['auth', 'status'], { stdio: 'inherit' });
|
|
138
|
+
child.on('close', resolve);
|
|
139
|
+
child.on('error', resolve);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
console.log('');
|
|
143
|
+
|
|
144
|
+
// 2. Get git config user.name
|
|
145
|
+
console.log(`2. Git user.name (${scope}):`);
|
|
146
|
+
console.log(` $ git config ${scopeFlag} user.name`);
|
|
147
|
+
|
|
148
|
+
const identity = await verifyGitIdentity({ scope, verbose });
|
|
149
|
+
|
|
150
|
+
if (identity.username) {
|
|
151
|
+
console.log(` ${identity.username}`);
|
|
152
|
+
} else {
|
|
153
|
+
console.log(' (not set)');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
console.log('');
|
|
157
|
+
|
|
158
|
+
// 3. Get git config user.email
|
|
159
|
+
console.log(`3. Git user.email (${scope}):`);
|
|
160
|
+
console.log(` $ git config ${scopeFlag} user.email`);
|
|
161
|
+
|
|
162
|
+
if (identity.email) {
|
|
163
|
+
console.log(` ${identity.email}`);
|
|
164
|
+
} else {
|
|
165
|
+
console.log(' (not set)');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log('');
|
|
169
|
+
console.log('Verification complete!');
|
|
170
|
+
}
|
|
171
|
+
|
|
57
172
|
/**
|
|
58
173
|
* Main CLI function
|
|
59
174
|
*/
|
|
@@ -62,19 +177,38 @@ async function main() {
|
|
|
62
177
|
// Determine scope
|
|
63
178
|
const scope = config.local ? 'local' : 'global';
|
|
64
179
|
|
|
180
|
+
// Handle --verify mode
|
|
181
|
+
if (config.verify) {
|
|
182
|
+
await runVerify(scope, config.verbose);
|
|
183
|
+
process.exit(0);
|
|
184
|
+
}
|
|
185
|
+
|
|
65
186
|
// Check if gh is authenticated
|
|
66
187
|
const authenticated = await isGhAuthenticated({ verbose: config.verbose });
|
|
67
188
|
|
|
68
189
|
if (!authenticated) {
|
|
69
190
|
console.log('GitHub CLI is not authenticated. Starting authentication...');
|
|
70
191
|
|
|
71
|
-
//
|
|
72
|
-
const
|
|
192
|
+
// Prepare auth options from CLI arguments
|
|
193
|
+
const authOptions = {
|
|
194
|
+
hostname: config.hostname,
|
|
195
|
+
scopes: config.scopes,
|
|
196
|
+
gitProtocol: config.gitProtocol,
|
|
197
|
+
web: config.web,
|
|
198
|
+
withToken: config.withToken,
|
|
199
|
+
skipSshKey: config.skipSshKey,
|
|
200
|
+
insecureStorage: config.insecureStorage,
|
|
201
|
+
clipboard: config.clipboard,
|
|
202
|
+
verbose: config.verbose
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Automatically run gh auth login with configured options
|
|
206
|
+
const loginSuccess = await runGhAuthLogin(authOptions);
|
|
73
207
|
|
|
74
208
|
if (!loginSuccess) {
|
|
75
209
|
console.log('');
|
|
76
210
|
console.log('Authentication failed. Please try running manually:');
|
|
77
|
-
console.log(
|
|
211
|
+
console.log(` printf "y" | gh auth login -h ${config.hostname} -s ${config.scopes} --git-protocol ${config.gitProtocol} --web`);
|
|
78
212
|
process.exit(1);
|
|
79
213
|
}
|
|
80
214
|
}
|
package/src/index.js
CHANGED
|
@@ -114,27 +114,97 @@ function execInteractiveCommand(command, args = [], options = {}) {
|
|
|
114
114
|
});
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Default options for gh auth login
|
|
119
|
+
*/
|
|
120
|
+
export const defaultAuthOptions = {
|
|
121
|
+
hostname: 'github.com',
|
|
122
|
+
scopes: 'repo,workflow,user,read:org,gist',
|
|
123
|
+
gitProtocol: 'https',
|
|
124
|
+
web: true,
|
|
125
|
+
withToken: false,
|
|
126
|
+
skipSshKey: false,
|
|
127
|
+
insecureStorage: false,
|
|
128
|
+
clipboard: false
|
|
129
|
+
};
|
|
130
|
+
|
|
117
131
|
/**
|
|
118
132
|
* Run gh auth login interactively
|
|
119
133
|
*
|
|
120
134
|
* @param {Object} options - Options
|
|
135
|
+
* @param {string} options.hostname - GitHub hostname (default: 'github.com')
|
|
136
|
+
* @param {string} options.scopes - OAuth scopes, comma-separated (default: 'repo,workflow,user,read:org,gist')
|
|
137
|
+
* @param {string} options.gitProtocol - Git protocol: 'ssh' or 'https' (default: 'https')
|
|
138
|
+
* @param {boolean} options.web - Open browser to authenticate (default: true)
|
|
139
|
+
* @param {boolean} options.withToken - Read token from stdin (default: false)
|
|
140
|
+
* @param {boolean} options.skipSshKey - Skip SSH key generation/upload prompt (default: false)
|
|
141
|
+
* @param {boolean} options.insecureStorage - Store credentials in plain text (default: false)
|
|
142
|
+
* @param {boolean} options.clipboard - Copy OAuth code to clipboard (default: false)
|
|
121
143
|
* @param {boolean} options.verbose - Enable verbose logging
|
|
122
144
|
* @param {Object} options.logger - Custom logger
|
|
123
145
|
* @returns {Promise<boolean>} True if login was successful
|
|
124
146
|
*/
|
|
125
147
|
export async function runGhAuthLogin(options = {}) {
|
|
126
|
-
const {
|
|
148
|
+
const {
|
|
149
|
+
hostname = defaultAuthOptions.hostname,
|
|
150
|
+
scopes = defaultAuthOptions.scopes,
|
|
151
|
+
gitProtocol = defaultAuthOptions.gitProtocol,
|
|
152
|
+
web = defaultAuthOptions.web,
|
|
153
|
+
withToken = defaultAuthOptions.withToken,
|
|
154
|
+
skipSshKey = defaultAuthOptions.skipSshKey,
|
|
155
|
+
insecureStorage = defaultAuthOptions.insecureStorage,
|
|
156
|
+
clipboard = defaultAuthOptions.clipboard,
|
|
157
|
+
verbose = false,
|
|
158
|
+
logger = console
|
|
159
|
+
} = options;
|
|
160
|
+
|
|
127
161
|
const log = createDefaultLogger({ verbose, logger });
|
|
128
162
|
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
'-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
163
|
+
// Build the arguments for gh auth login
|
|
164
|
+
const args = ['auth', 'login'];
|
|
165
|
+
|
|
166
|
+
// Add hostname
|
|
167
|
+
if (hostname) {
|
|
168
|
+
args.push('-h', hostname);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Add scopes
|
|
172
|
+
if (scopes) {
|
|
173
|
+
args.push('-s', scopes);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Add git protocol
|
|
177
|
+
if (gitProtocol) {
|
|
178
|
+
args.push('--git-protocol', gitProtocol);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Add boolean flags
|
|
182
|
+
if (web && !withToken) {
|
|
183
|
+
args.push('--web');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (withToken) {
|
|
187
|
+
args.push('--with-token');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (skipSshKey) {
|
|
191
|
+
args.push('--skip-ssh-key');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (insecureStorage) {
|
|
195
|
+
args.push('--insecure-storage');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (clipboard && web && !withToken) {
|
|
199
|
+
args.push('--clipboard');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
log.debug(() => `Running: gh ${args.join(' ')}`);
|
|
203
|
+
|
|
204
|
+
// Run gh auth login
|
|
205
|
+
// Use 'y' as input to confirm default account selection (only needed for interactive mode)
|
|
206
|
+
const inputValue = withToken ? undefined : 'y\n';
|
|
207
|
+
const result = await execInteractiveCommand('gh', args, { input: inputValue });
|
|
138
208
|
|
|
139
209
|
if (result.exitCode !== 0) {
|
|
140
210
|
log.error(() => 'GitHub CLI authentication failed');
|
|
@@ -368,6 +438,7 @@ export async function verifyGitIdentity(options = {}) {
|
|
|
368
438
|
}
|
|
369
439
|
|
|
370
440
|
export default {
|
|
441
|
+
defaultAuthOptions,
|
|
371
442
|
isGhAuthenticated,
|
|
372
443
|
runGhAuthLogin,
|
|
373
444
|
getGitHubUsername,
|
package/test/index.test.js
CHANGED
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
getGitHubEmail,
|
|
11
11
|
getGitHubUserInfo,
|
|
12
12
|
getGitConfig,
|
|
13
|
-
verifyGitIdentity
|
|
13
|
+
verifyGitIdentity,
|
|
14
|
+
defaultAuthOptions
|
|
14
15
|
} from '../src/index.js';
|
|
15
16
|
|
|
16
17
|
// Note: These tests require gh to be authenticated
|
|
@@ -89,10 +90,42 @@ test('runGhAuthLogin - is exported as a function', async () => {
|
|
|
89
90
|
assert.equal(typeof runGhAuthLogin, 'function');
|
|
90
91
|
});
|
|
91
92
|
|
|
93
|
+
// Test: defaultAuthOptions is exported and has correct structure
|
|
94
|
+
test('defaultAuthOptions - is exported with correct default values', async () => {
|
|
95
|
+
assert.ok(typeof defaultAuthOptions === 'object');
|
|
96
|
+
assert.equal(defaultAuthOptions.hostname, 'github.com');
|
|
97
|
+
assert.equal(defaultAuthOptions.scopes, 'repo,workflow,user,read:org,gist');
|
|
98
|
+
assert.equal(defaultAuthOptions.gitProtocol, 'https');
|
|
99
|
+
assert.equal(defaultAuthOptions.web, true);
|
|
100
|
+
assert.equal(defaultAuthOptions.withToken, false);
|
|
101
|
+
assert.equal(defaultAuthOptions.skipSshKey, false);
|
|
102
|
+
assert.equal(defaultAuthOptions.insecureStorage, false);
|
|
103
|
+
assert.equal(defaultAuthOptions.clipboard, false);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Test: defaultAuthOptions contains all expected keys
|
|
107
|
+
test('defaultAuthOptions - contains all expected keys', async () => {
|
|
108
|
+
const expectedKeys = [
|
|
109
|
+
'hostname',
|
|
110
|
+
'scopes',
|
|
111
|
+
'gitProtocol',
|
|
112
|
+
'web',
|
|
113
|
+
'withToken',
|
|
114
|
+
'skipSshKey',
|
|
115
|
+
'insecureStorage',
|
|
116
|
+
'clipboard'
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
for (const key of expectedKeys) {
|
|
120
|
+
assert.ok(key in defaultAuthOptions, `Missing key: ${key}`);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
92
124
|
// Test: module exports
|
|
93
125
|
test('module exports all expected functions', async () => {
|
|
94
126
|
const module = await import('../src/index.js');
|
|
95
127
|
|
|
128
|
+
assert.ok(typeof module.defaultAuthOptions === 'object');
|
|
96
129
|
assert.ok(typeof module.isGhAuthenticated === 'function');
|
|
97
130
|
assert.ok(typeof module.runGhAuthLogin === 'function');
|
|
98
131
|
assert.ok(typeof module.getGitHubUsername === 'function');
|
|
@@ -110,6 +143,7 @@ test('default export contains all functions', async () => {
|
|
|
110
143
|
const defaultExport = module.default;
|
|
111
144
|
|
|
112
145
|
assert.ok(typeof defaultExport === 'object');
|
|
146
|
+
assert.ok(typeof defaultExport.defaultAuthOptions === 'object');
|
|
113
147
|
assert.ok(typeof defaultExport.isGhAuthenticated === 'function');
|
|
114
148
|
assert.ok(typeof defaultExport.runGhAuthLogin === 'function');
|
|
115
149
|
assert.ok(typeof defaultExport.getGitHubUsername === 'function');
|