opensocrates 1.3.1 → 1.4.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 +21 -0
- package/README.ko.md +72 -81
- package/README.md +71 -81
- package/SECURITY.md +59 -141
- package/VERSION +1 -1
- package/installer/opensocrates.mjs +570 -1346
- package/installer/windows.ps1 +45 -0
- package/package.json +6 -12
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Paths are data in environment variables, never interpolated PowerShell code.
|
|
2
|
+
param([ValidateSet('entries','extract','private')][string]$Action)
|
|
3
|
+
$ErrorActionPreference = 'Stop'
|
|
4
|
+
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
|
|
5
|
+
$targetPath = $env:OPENSOCRATES_WINDOWS_PATH
|
|
6
|
+
if ($Action -eq 'private') {
|
|
7
|
+
$item = Get-Item -LiteralPath $targetPath -Force
|
|
8
|
+
if ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Reparse point refused' }
|
|
9
|
+
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
10
|
+
$acl = $item.GetAccessControl()
|
|
11
|
+
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -ne $sid.Value) { throw 'Foreign owner refused' }
|
|
12
|
+
$acl.SetAccessRuleProtection($true, $false)
|
|
13
|
+
foreach ($rule in @($acl.Access)) { [void]$acl.RemoveAccessRuleSpecific($rule) }
|
|
14
|
+
$inherit = if ($item.PSIsContainer) { 'ContainerInherit,ObjectInherit' } else { 'None' }
|
|
15
|
+
foreach ($identity in @($sid.Value,'S-1-5-18','S-1-5-32-544')) {
|
|
16
|
+
$rule = [Security.AccessControl.FileSystemAccessRule]::new([Security.Principal.SecurityIdentifier]::new($identity), 'FullControl', $inherit, 'None', 'Allow')
|
|
17
|
+
$acl.AddAccessRule($rule)
|
|
18
|
+
}
|
|
19
|
+
$item.SetAccessControl($acl)
|
|
20
|
+
exit 0
|
|
21
|
+
}
|
|
22
|
+
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
23
|
+
$zip = [IO.Compression.ZipFile]::OpenRead($targetPath)
|
|
24
|
+
try {
|
|
25
|
+
$names = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
|
|
26
|
+
$total = 0L
|
|
27
|
+
foreach ($entry in $zip.Entries) {
|
|
28
|
+
$name = $entry.FullName
|
|
29
|
+
$parts = $name.TrimEnd('/').Split('/')
|
|
30
|
+
if (!$name -or $name.Contains('\') -or $name.StartsWith('/') -or $name -match '[\x00-\x1f<>:"|?*]' -or
|
|
31
|
+
($parts | Where-Object { !$_ -or $_ -eq '.' -or $_ -eq '..' -or $_ -match '[. ]$' -or $_ -match '^(?i:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)' }) -or !$names.Add($name.TrimEnd('/'))) { throw 'Unsafe or duplicate ZIP path' }
|
|
32
|
+
if ((($entry.ExternalAttributes -shr 16) -band 0xF000) -eq 0xA000) { throw 'ZIP symlink refused' }
|
|
33
|
+
$total += $entry.Length
|
|
34
|
+
if ($total -gt 2147483648 -or $zip.Entries.Count -gt 20000) { throw 'ZIP limit exceeded' }
|
|
35
|
+
}
|
|
36
|
+
if ($Action -eq 'entries') { ConvertTo-Json -InputObject @($zip.Entries | ForEach-Object { $_.FullName }) -Compress; exit 0 }
|
|
37
|
+
$destination = [IO.Path]::GetFullPath($env:OPENSOCRATES_WINDOWS_DESTINATION).TrimEnd('\') + '\'
|
|
38
|
+
foreach ($entry in $zip.Entries) {
|
|
39
|
+
$output = [IO.Path]::GetFullPath([IO.Path]::Combine($destination,$entry.FullName))
|
|
40
|
+
if (!$output.StartsWith($destination,[StringComparison]::OrdinalIgnoreCase)) { throw 'ZIP path escape' }
|
|
41
|
+
if ($entry.FullName.EndsWith('/')) { [void][IO.Directory]::CreateDirectory($output); continue }
|
|
42
|
+
[void][IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($output))
|
|
43
|
+
[IO.Compression.ZipFileExtensions]::ExtractToFile($entry,$output,$false)
|
|
44
|
+
}
|
|
45
|
+
} finally { $zip.Dispose() }
|
package/package.json
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opensocrates",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Install and manage OpenSocrates for
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Install and manage OpenSocrates for Codex on macOS and Windows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"opensocrates": "installer/opensocrates.mjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"installer/opensocrates.mjs",
|
|
11
|
+
"installer/windows.ps1",
|
|
11
12
|
"CHANGELOG.md",
|
|
12
13
|
"SECURITY.md",
|
|
13
14
|
"VERSION"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
|
-
"test": "node --test installer/opensocrates.test.mjs installer/lifecycle.test.mjs tools/clean_machine_acceptance.test.mjs tools/reinstall_cycle_acceptance.test.mjs tools/
|
|
17
|
+
"test": "node --test installer/opensocrates.test.mjs installer/lifecycle.test.mjs tools/clean_machine_acceptance.test.mjs tools/reinstall_cycle_acceptance.test.mjs tools/release_gate.test.mjs && npm run test:npx",
|
|
17
18
|
"test:npx": "node installer/package-smoke.mjs",
|
|
18
19
|
"pack:check": "npm pack --dry-run",
|
|
19
|
-
"prepublishOnly": "npm test"
|
|
20
|
+
"prepublishOnly": "npm test",
|
|
21
|
+
"test:windows": "node --test installer/windows.test.mjs"
|
|
20
22
|
},
|
|
21
23
|
"engines": {
|
|
22
24
|
"node": ">=20"
|
|
@@ -36,17 +38,9 @@
|
|
|
36
38
|
},
|
|
37
39
|
"keywords": [
|
|
38
40
|
"ai",
|
|
39
|
-
"claude",
|
|
40
|
-
"claude-code",
|
|
41
41
|
"codex",
|
|
42
|
-
"grok",
|
|
43
|
-
"grok-build",
|
|
44
|
-
"cowork",
|
|
45
|
-
"cursor",
|
|
46
|
-
"opencode",
|
|
47
42
|
"reasoning",
|
|
48
43
|
"agent",
|
|
49
|
-
"antigravity",
|
|
50
44
|
"installer",
|
|
51
45
|
"critical-thinking",
|
|
52
46
|
"socratic"
|