pinokiod 7.3.3 → 7.3.4
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/kernel/git.js +29 -1
- package/package.json +1 -1
- package/test/git-defaults.test.js +53 -0
package/kernel/git.js
CHANGED
|
@@ -1169,6 +1169,32 @@ class Git {
|
|
|
1169
1169
|
}
|
|
1170
1170
|
}
|
|
1171
1171
|
}
|
|
1172
|
+
const clone = (value) => {
|
|
1173
|
+
if (typeof value !== "object" || value === null) return value
|
|
1174
|
+
return JSON.parse(JSON.stringify(value))
|
|
1175
|
+
}
|
|
1176
|
+
const sameConfigValue = (a, b) => JSON.stringify(a) === JSON.stringify(b)
|
|
1177
|
+
const isCredentialSection = (section) => section === "credential" || section.startsWith('credential "')
|
|
1178
|
+
const resetCredentialDefaults = () => {
|
|
1179
|
+
const templateCredentialSections = Object.fromEntries(
|
|
1180
|
+
Object.entries(templateConfig).filter(([section]) => isCredentialSection(section))
|
|
1181
|
+
)
|
|
1182
|
+
|
|
1183
|
+
for (const section of Object.keys(config)) {
|
|
1184
|
+
if (!isCredentialSection(section)) continue
|
|
1185
|
+
if (!Object.prototype.hasOwnProperty.call(templateCredentialSections, section)) {
|
|
1186
|
+
delete config[section]
|
|
1187
|
+
dirty = true
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
for (const [section, tplSection] of Object.entries(templateCredentialSections)) {
|
|
1192
|
+
if (!sameConfigValue(config[section], tplSection)) {
|
|
1193
|
+
config[section] = clone(tplSection)
|
|
1194
|
+
dirty = true
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1172
1198
|
|
|
1173
1199
|
for (const [section, tplSection] of Object.entries(templateConfig)) {
|
|
1174
1200
|
if (typeof tplSection !== "object" || tplSection === null) continue
|
|
@@ -1196,6 +1222,8 @@ class Git {
|
|
|
1196
1222
|
dirty = true
|
|
1197
1223
|
}
|
|
1198
1224
|
|
|
1225
|
+
resetCredentialDefaults()
|
|
1226
|
+
|
|
1199
1227
|
const githubCredentialSection = config['credential "https://github'] && config['credential "https://github']['com"']
|
|
1200
1228
|
if (githubCredentialSection && typeof githubCredentialSection === "object") {
|
|
1201
1229
|
if (!githubCredentialSection.provider) {
|
|
@@ -1203,7 +1231,7 @@ class Git {
|
|
|
1203
1231
|
dirty = true
|
|
1204
1232
|
}
|
|
1205
1233
|
const helper = typeof githubCredentialSection.helper === "string" ? githubCredentialSection.helper : ""
|
|
1206
|
-
if (!helper
|
|
1234
|
+
if (!helper) {
|
|
1207
1235
|
githubCredentialSection.helper = "manager"
|
|
1208
1236
|
dirty = true
|
|
1209
1237
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
const assert = require('node:assert/strict')
|
|
2
|
+
const { execFile } = require('node:child_process')
|
|
2
3
|
const fs = require('node:fs/promises')
|
|
3
4
|
const os = require('node:os')
|
|
4
5
|
const path = require('node:path')
|
|
5
6
|
const test = require('node:test')
|
|
7
|
+
const { promisify } = require('node:util')
|
|
6
8
|
const ini = require('ini')
|
|
7
9
|
|
|
8
10
|
const KernelGit = require('../kernel/git')
|
|
11
|
+
const execFileAsync = promisify(execFile)
|
|
9
12
|
|
|
10
13
|
async function withTempHome(fn) {
|
|
11
14
|
const homedir = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-git-defaults-'))
|
|
@@ -67,6 +70,56 @@ test('Git defaults migrate the legacy gh GitHub helper to Git Credential Manager
|
|
|
67
70
|
})
|
|
68
71
|
})
|
|
69
72
|
|
|
73
|
+
test('Git defaults reset credential sections to built-in defaults before Git reads config', async () => {
|
|
74
|
+
await withTempHome(async (homedir) => {
|
|
75
|
+
const staleHelpers = [
|
|
76
|
+
'!custom-helper auth git-credential',
|
|
77
|
+
'!gh auth git-credential',
|
|
78
|
+
'!gh.exe auth git-credential',
|
|
79
|
+
`!'${path.win32.join('Z:\\', 'Any Folder', 'bin', 'gh.exe')}' auth git-credential`,
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
for (const [index, helper] of staleHelpers.entries()) {
|
|
83
|
+
const caseHome = path.join(homedir, `case-${index}`)
|
|
84
|
+
await fs.mkdir(caseHome)
|
|
85
|
+
const gitconfigPath = path.join(caseHome, 'gitconfig')
|
|
86
|
+
await fs.writeFile(gitconfigPath, [
|
|
87
|
+
'[credential "https://github.com"]',
|
|
88
|
+
` helper = ${helper}`,
|
|
89
|
+
' provider = github',
|
|
90
|
+
'[credential "https://gist.github.com"]',
|
|
91
|
+
` helper = ${helper}`,
|
|
92
|
+
'[credential "https://enterprise.example"]',
|
|
93
|
+
` helper = ${helper}`,
|
|
94
|
+
'[credential]',
|
|
95
|
+
` helper = ${helper}`,
|
|
96
|
+
' gitHubAuthModes = device',
|
|
97
|
+
' namespace = stale',
|
|
98
|
+
'[user]',
|
|
99
|
+
' name = custom',
|
|
100
|
+
' email = custom@example.test',
|
|
101
|
+
'',
|
|
102
|
+
].join('\n'))
|
|
103
|
+
const git = new KernelGit(createKernel(caseHome))
|
|
104
|
+
|
|
105
|
+
await git.ensureDefaults()
|
|
106
|
+
|
|
107
|
+
const content = await fs.readFile(gitconfigPath, 'utf8')
|
|
108
|
+
assert.doesNotMatch(content, /git-credential/i)
|
|
109
|
+
const { stdout } = await execFileAsync('git', ['config', '--file', gitconfigPath, '--list'])
|
|
110
|
+
assert.match(stdout, /credential\.helper=manager/)
|
|
111
|
+
assert.match(stdout, /credential\.githubauthmodes=oauth/)
|
|
112
|
+
assert.match(stdout, /credential\.namespace=pinokio/)
|
|
113
|
+
assert.match(stdout, /credential\.https:\/\/github\.com\.helper=manager/)
|
|
114
|
+
assert.doesNotMatch(stdout, /credential\.https:\/\/gist\.github\.com/)
|
|
115
|
+
assert.doesNotMatch(stdout, /credential\.https:\/\/enterprise\.example/)
|
|
116
|
+
const config = ini.parse(content)
|
|
117
|
+
assert.equal(config.user.name, 'custom')
|
|
118
|
+
assert.equal(config.user.email, 'custom@example.test')
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
70
123
|
test('Git isomorphic auth callback returns GCM credentials for GitHub URLs', async () => {
|
|
71
124
|
const git = new KernelGit(createKernel('/tmp/pinokio'))
|
|
72
125
|
let requestedUrl = ''
|