Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/pnpmPublic

Commit7730a7f

Browse files
Aeolunzkochan
andauthored
feat: allow loading certificates from scopedcert,ca andkey (#10230)
* feat: allow loading certificates from `cert`, `ca` and `key`These properties are supported in .npmrc, but get ignored by pnpm, this will make pnpm readand use them as well.* refactor: getNetworkConfigs.ts* docs: update changesets* fix: issues* docs: update changesets---------Co-authored-by: Zoltan Kochan <z@kochan.io>
1 parent49c1b9c commit7730a7f

File tree

4 files changed

+77
-14
lines changed

4 files changed

+77
-14
lines changed

‎.changeset/all-tables-speak.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@pnpm/config":minor
3+
"pnpm":minor
4+
---
5+
6+
Allow loading certificates from`cert`,`ca`, and`key` for specific registry URLs. E.g.,`//registry.example.com/:ca=-----BEGIN CERTIFICATE-----...`. Previously this was only working via`certfile`,`cafile`, and`keyfile`.
7+
8+
These properties are supported in`.npmrc`, but were ignored by pnpm, this will make pnpm read and use them as well.
9+
10+
Related PR:[#10230](https://github.com/pnpm/pnpm/pull/10230).

‎config/config/src/auth.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ const RAW_AUTH_CFG_KEYS = [
1717
]satisfiesArray<keyoftypeoftypes>
1818

1919
constRAW_AUTH_CFG_KEY_SUFFIXES=[
20+
':ca',
2021
':cafile',
22+
':cert',
2123
':certfile',
24+
':key',
2225
':keyfile',
2326
':registry',
2427
':tokenHelper',

‎config/config/src/getNetworkConfigs.ts‎

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,47 @@ export interface GetNetworkConfigsResult {
88
}
99

1010
exportfunctiongetNetworkConfigs(rawConfig:Record<string,object>):GetNetworkConfigsResult{
11-
// Get all the auth options that have:certfile or :keyfile in their name
11+
// Get all the auth options that haveSSL certificate data or file references
1212
constsslConfigs:Record<string,SslConfig>={}
1313
constregistries:Record<string,string>={}
1414
for(const[configKey,value]ofObject.entries(rawConfig)){
1515
if(configKey[0]==='@'&&configKey.endsWith(':registry')){
1616
registries[configKey.slice(0,configKey.indexOf(':'))]=normalizeRegistryUrl(valueasunknownasstring)
17-
}elseif(configKey.includes(':certfile')||configKey.includes(':keyfile')||configKey.includes(':cafile')){
18-
// Split by '/:' because the registry may contain a port
19-
constregistry=configKey.split('/:')[0]+'/'
20-
if(!sslConfigs[registry]){
21-
sslConfigs[registry]={cert:'',key:''}
22-
}
23-
if(configKey.includes(':certfile')){
24-
sslConfigs[registry].cert=fs.readFileSync(valueasunknownasstring,'utf8')
25-
}elseif(configKey.includes(':keyfile')){
26-
sslConfigs[registry].key=fs.readFileSync(valueasunknownasstring,'utf8')
27-
}elseif(configKey.includes(':cafile')){
28-
sslConfigs[registry].ca=fs.readFileSync(valueasunknownasstring,'utf8')
29-
}
17+
continue
3018
}
19+
20+
constparsed=tryParseSslSetting(configKey)
21+
if(!parsed)continue
22+
23+
const{ registry, sslConfigKey, isFile}=parsed
24+
if(!sslConfigs[registry]){
25+
sslConfigs[registry]={cert:'',key:''}
26+
}
27+
sslConfigs[registry][sslConfigKey]=isFile
28+
?fs.readFileSync(valueasunknownasstring,'utf8')
29+
:(valueasunknownasstring).replace(/\\n/g,'\n')
3130
}
3231
return{
3332
registries,
3433
sslConfigs,
3534
}
3635
}
36+
37+
constSSL_SUFFIX_RE=/:(?<id>cert|key|ca)(?<kind>file)?$/
38+
39+
interfaceParsedSslSetting{
40+
registry:string
41+
sslConfigKey:keyofSslConfig
42+
isFile:boolean
43+
}
44+
45+
functiontryParseSslSetting(key:string):ParsedSslSetting|null{
46+
constmatch=key.match(SSL_SUFFIX_RE)
47+
if(!match?.groups){
48+
returnnull
49+
}
50+
constregistry=key.slice(0,match.index!)// already includes the trailing slash
51+
constsslConfigKey=match.groups.idaskeyofSslConfig
52+
constisFile=Boolean(match.groups.kind)
53+
return{ registry, sslConfigKey, isFile}
54+
}

‎config/config/test/index.ts‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,38 @@ test('getConfig() should read cafile', async () => {
981981
-----END CERTIFICATE-----`])
982982
})
983983

984+
test('getConfig() should read inline SSL certificates from .npmrc',async()=>{
985+
prepareEmpty()
986+
987+
// These are written to .npmrc with literal \n strings
988+
constinlineCa='-----BEGIN CERTIFICATE-----\\nMIIFNzCCAx+gAwIBAgIQNB613yRzpKtDztlXiHmOGDANBgkqhkiG9w0BAQsFADAR\\n-----END CERTIFICATE-----'
989+
constinlineCert='-----BEGIN CERTIFICATE-----\\nMIIClientCert\\n-----END CERTIFICATE-----'
990+
constinlineKey='-----BEGIN PRIVATE KEY-----\\nMIIClientKey\\n-----END PRIVATE KEY-----'
991+
992+
constnpmrc=[
993+
'//registry.example.com/:ca='+inlineCa,
994+
'//registry.example.com/:cert='+inlineCert,
995+
'//registry.example.com/:key='+inlineKey,
996+
].join('\n')
997+
fs.writeFileSync('.npmrc',npmrc,'utf8')
998+
999+
const{ config}=awaitgetConfig({
1000+
cliOptions:{},
1001+
packageManager:{
1002+
name:'pnpm',
1003+
version:'1.0.0',
1004+
},
1005+
})
1006+
1007+
// After processing, \n should be converted to actual newlines
1008+
expect(config.sslConfigs).toBeDefined()
1009+
expect(config.sslConfigs['//registry.example.com/']).toStrictEqual({
1010+
ca:inlineCa.replace(/\\n/g,'\n'),
1011+
cert:inlineCert.replace(/\\n/g,'\n'),
1012+
key:inlineKey.replace(/\\n/g,'\n'),
1013+
})
1014+
})
1015+
9841016
test('respect mergeGitBranchLockfilesBranchPattern',async()=>{
9851017
{
9861018
prepareEmpty()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp