176 lines
5.5 KiB
PowerShell
176 lines
5.5 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$Cookie,
|
|
[string]$CookieStore = "plugins/1c/rag/official-docs/.local/its-cookie.dpapi.txt",
|
|
[switch]$Console,
|
|
[switch]$SkipValidate,
|
|
[switch]$PrintEnvCommand
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Add-Type -AssemblyName System.Security
|
|
|
|
function Decode-Utf8Base64([string]$Text) {
|
|
return [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Text))
|
|
}
|
|
|
|
function Get-CookieFromDialog {
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
Add-Type -AssemblyName System.Drawing
|
|
|
|
$form = New-Object System.Windows.Forms.Form
|
|
$form.Text = "1C:ITS Cookie"
|
|
$form.Width = 820
|
|
$form.Height = 360
|
|
$form.StartPosition = "CenterScreen"
|
|
$form.TopMost = $true
|
|
$form.Font = New-Object System.Drawing.Font("Segoe UI", 9)
|
|
|
|
$label = New-Object System.Windows.Forms.Label
|
|
$label.Text = "Paste Cookie header from an authorized its.1c.ru request."
|
|
$label.Left = 12
|
|
$label.Top = 12
|
|
$label.Width = 770
|
|
$label.Height = 24
|
|
$form.Controls.Add($label)
|
|
|
|
$hint = New-Object System.Windows.Forms.Label
|
|
$hint.Text = "Chrome DevTools -> Network -> open its.1c.ru page -> Request Headers -> Cookie. Do not paste yandex.com cookies."
|
|
$hint.Left = 12
|
|
$hint.Top = 34
|
|
$hint.Width = 770
|
|
$hint.Height = 24
|
|
$hint.ForeColor = [System.Drawing.Color]::DarkRed
|
|
$form.Controls.Add($hint)
|
|
|
|
$textBox = New-Object System.Windows.Forms.TextBox
|
|
$textBox.Left = 12
|
|
$textBox.Top = 64
|
|
$textBox.Width = 780
|
|
$textBox.Height = 198
|
|
$textBox.Multiline = $true
|
|
$textBox.ScrollBars = "Vertical"
|
|
$textBox.AcceptsReturn = $true
|
|
$textBox.AcceptsTab = $true
|
|
$form.Controls.Add($textBox)
|
|
|
|
$ok = New-Object System.Windows.Forms.Button
|
|
$ok.Text = Decode-Utf8Base64 "0KHQvtGF0YDQsNC90LjRgtGM"
|
|
$ok.Left = 606
|
|
$ok.Top = 276
|
|
$ok.Width = 90
|
|
$ok.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
|
$form.AcceptButton = $ok
|
|
$form.Controls.Add($ok)
|
|
|
|
$cancel = New-Object System.Windows.Forms.Button
|
|
$cancel.Text = Decode-Utf8Base64 "0J7RgtC80LXQvdCw"
|
|
$cancel.Left = 704
|
|
$cancel.Top = 276
|
|
$cancel.Width = 90
|
|
$cancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
|
|
$form.CancelButton = $cancel
|
|
$form.Controls.Add($cancel)
|
|
|
|
$result = $form.ShowDialog()
|
|
if ($result -ne [System.Windows.Forms.DialogResult]::OK) {
|
|
throw "Cookie input cancelled."
|
|
}
|
|
return $textBox.Text.Trim()
|
|
}
|
|
|
|
function Test-CookieShape([string]$Text) {
|
|
$warnings = New-Object System.Collections.Generic.List[string]
|
|
if ($Text -match '(?i)yandex\.') {
|
|
$warnings.Add("Cookie text contains yandex.* marker. This is probably not the 1C:ITS auth cookie.")
|
|
}
|
|
if ($Text -match '(?i)\bdomain\s*=\s*\.?(?!its\.1c\.ru)') {
|
|
$warnings.Add("Cookie text contains a non-its.1c.ru Domain attribute.")
|
|
}
|
|
if ($Text -notmatch '=') {
|
|
$warnings.Add("Cookie text does not look like name=value pairs.")
|
|
}
|
|
return $warnings.ToArray()
|
|
}
|
|
|
|
function Normalize-ItsCookie([string]$Text) {
|
|
$tempFile = [System.IO.Path]::GetTempFileName()
|
|
try {
|
|
Set-Content -LiteralPath $tempFile -Value $Text -Encoding UTF8
|
|
$json = python -X utf8 scripts/normalize_1c_its_cookie.py --input-file $tempFile 2>&1
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Cookie normalization failed: $json"
|
|
}
|
|
$result = $json | ConvertFrom-Json
|
|
if (-not $result.ok) {
|
|
throw "Cookie normalization rejected input: $($result.errors -join ', ')"
|
|
}
|
|
if ($result.warnings -and $result.warnings.Count -gt 0) {
|
|
Write-Warning "Cookie normalization warnings: $($result.warnings -join ', ')"
|
|
}
|
|
Write-Host "Normalized cookie format: $($result.format), pairs: $($result.pair_count)"
|
|
return [string]$result.cookie
|
|
} finally {
|
|
Remove-Item -LiteralPath $tempFile -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
function Protect-Text([string]$Text) {
|
|
$bytes = [System.Text.Encoding]::UTF8.GetBytes($Text)
|
|
$protected = [System.Security.Cryptography.ProtectedData]::Protect(
|
|
$bytes,
|
|
$null,
|
|
[System.Security.Cryptography.DataProtectionScope]::CurrentUser
|
|
)
|
|
return [Convert]::ToBase64String($protected)
|
|
}
|
|
|
|
if (-not $Cookie) {
|
|
if ($Console) {
|
|
$Cookie = Read-Host "Paste 1C:ITS Cookie"
|
|
} else {
|
|
try {
|
|
$Cookie = Get-CookieFromDialog
|
|
} catch {
|
|
Write-Warning "GUI input failed: $($_.Exception.Message)"
|
|
$Cookie = Read-Host "Paste 1C:ITS Cookie"
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($null -eq $Cookie) {
|
|
$Cookie = ""
|
|
}
|
|
$Cookie = $Cookie.Trim()
|
|
if (-not $Cookie) {
|
|
throw "Cookie is empty."
|
|
}
|
|
|
|
$shapeWarnings = Test-CookieShape $Cookie
|
|
if ($shapeWarnings.Count -gt 0) {
|
|
Write-Warning "Cookie shape warning:"
|
|
foreach ($warning in $shapeWarnings) {
|
|
Write-Warning " - $warning"
|
|
}
|
|
}
|
|
|
|
$Cookie = Normalize-ItsCookie $Cookie
|
|
|
|
$storePath = Resolve-Path -LiteralPath (Split-Path -Parent $CookieStore) -ErrorAction SilentlyContinue
|
|
if (-not $storePath) {
|
|
New-Item -ItemType Directory -Path (Split-Path -Parent $CookieStore) -Force | Out-Null
|
|
}
|
|
|
|
Protect-Text $Cookie | Set-Content -LiteralPath $CookieStore -Encoding UTF8
|
|
|
|
Write-Host "Saved encrypted 1C:ITS cookie to $CookieStore"
|
|
if (-not $SkipValidate) {
|
|
$env:ONEC_ITS_COOKIE = $Cookie
|
|
Write-Host "Validating 1C:ITS protected access..."
|
|
python -X utf8 scripts/check_1c_its_access.py --print
|
|
}
|
|
if ($PrintEnvCommand) {
|
|
Write-Host '$env:ONEC_ITS_COOKIE = "<stored encrypted; use scripts/run_1c_its_docs_pipeline.ps1>"'
|
|
}
|