fix(windows,tui): DPAPI over stdin, browser opener without cmd, tag capability check #12
Merged
james.maes
merged 3 commits from 2026-11-06 15:32:20 +00:00
fix/windows-dpapi-browser-tags-20261106 into main
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2c3114e06b
|
fix(tui): check the record's tag feature and capability before the tag editor
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 8s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 4s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
QRun-IO/ci-policy: Original QQQ CLI verification and package capture / secrets (pull_request) Successful in 18s
QRun-IO/ci-policy: Original QQQ CLI verification and package capture / verify (pull_request) Successful in 1m50s
QRun-IO/ci-policy: Original QQQ CLI verification and package capture / gate (pull_request) Successful in 16s
QRun-IO/ci-policy: ci / original-cli (pull_request) Successful in 2m8s
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 6s
The record screen opened the TagOverlay for any record whenever the collaboration extension was present. On a table without the TAGS feature, or for a role without the `tag` capability, the editor opened and the save failed only when the server refused it. openTags now calls getRecordFeatures for the record and opens the overlay only when `features` contains TAGS and `capabilities.tag` is true; otherwise it flashes "Tags are not enabled for this table." or "Your role cannot tag this record.". The answer is ignored when the screen has moved to another record meanwhile, and a request error is flashed like any other. Tests: the fake server answers /table/person/<id>/features from a `recordTagPolicy` (enabled, allowed; reset with the rest of the collaboration state), and enterprise.test.tsx presses t with the feature off and with the capability denied and expects the message and no overlay. The existing tag editor test keeps its defaults. Carried locally by GG Forge since cli-v1.0.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: James Maes <james@kof22.com> |
||
|
|
b126064144
|
fix(cli): open the browser on Windows without cmd /c start splitting the URL
openInBrowser used `cmd /c start "" <url>` on Windows. cmd treats `&` as a command separator even inside an argument that was passed as one string, so an OAuth authorization URL was cut at its first query parameter: the browser opened the authorization endpoint without client_id, state or redirect_uri and the loopback callback never arrived. Only `qqq login --browser` was affected; the printed URL worked when pasted. The URL is now never shell text. The opener runs PowerShell (QQQ_POWERSHELL, else powershell.exe) with a fixed -EncodedCommand, `Start-Process -FilePath $env:QQQ_BROWSER_URL`, and the URL in that environment variable; the child is detached, stdio ignored and windowsHide set so no console window flashes. Test (win32 only): stubs child_process.spawn to capture the call, checks the command is not cmd, the URL is in the environment and windowsHide is set, then runs the captured encoded command in a real PowerShell with Start-Process shadowed to print its -FilePath, and expects the full URL back, `&` and all. Carried locally by GG Forge since cli-v1.0.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: James Maes <james@kof22.com> |
||
|
|
a7767ba76c
|
fix(core): pass DPAPI secrets to PowerShell over stdin, not the command line
The Windows keyring (DpapiFileStore) interpolated the secret into the PowerShell -Command string with JSON.stringify. A token was therefore visible in the process list and in process-creation auditing for the lifetime of the call, and PowerShell's own parsing could still mangle quotes, backticks and $() inside the quoted value. The secret now goes over stdin: the fixed command sets UTF-8 on both console streams, reads stdin to the end, runs the protect or unprotect step on that value and writes the result as compact JSON, which the caller parses. Unprotect zeroes and frees the BSTR and disposes the SecureString after reading. Any subprocess failure, non-zero exit or non-string result is reported as "Windows credential protection failed; check PowerShell and your Windows profile", never with the arguments. Tests (win32 only): a round trip of a value with fake JSON, shell syntax, Unicode and surrounding whitespace that must not appear in the secrets file in clear, and a corrupt blob that must fail with the redacted message. Run with QQQ_POWERSHELL=pwsh where Windows PowerShell 5.1 cannot load Microsoft.PowerShell.Security. Carried locally by GG Forge since cli-v1.0.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: James Maes <james@kof22.com> |