initial commit

This commit is contained in:
2025-09-17 10:52:06 -05:00
commit 7e24c746e8
13 changed files with 2924 additions and 0 deletions

View File

@@ -0,0 +1,190 @@
# How to read/edit `store.dat` on Windows
## What this does
- Decrypts `%AppData%\rIDE\<userId>\store.dat` using Windows **DPAPI
(CurrentUser)**.
- Lets you **view** keys and **update** a value (e.g., `GithubToken`,
`SupabaseToken`, etc.).
- Must be run **as the same Windows user account** that created the
file.
------------------------------------------------------------------------
## 0) One-time setup
1. **Save the script** (name it exactly): `decrypt-dat-file.ps1`\
(Use the version Jimmy shared --- it already loads the
`System.Security` assembly and includes `Set-StoreValue`.)
2. Put it somewhere easy, e.g.:
C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1
------------------------------------------------------------------------
## 1) Open PowerShell & allow running the script (this session only)
``` powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```
------------------------------------------------------------------------
## 2) Find your `userId` folder and back up the file
`store.dat` lives at:
%AppData%\rIDE\<userId>\store.dat
In PowerShell, reference `%AppData%` as `$env:APPDATA`. Example:
``` powershell
# Replace <userId> with the actual folder name (GUID)
cd "$env:APPDATA\rIDE\<userId>"
Copy .\store.dat .\store.bak
```
> Tip: to list the available userId folders:
``` powershell
Get-ChildItem "$env:APPDATA\rIDE"
```
------------------------------------------------------------------------
## 3) List keys / read values (no edits yet)
### Option A --- run the script with parameters (no functions loaded)
Use the **call operator** `&` when passing parameters:
``` powershell
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -ListKeys
# Example output: GithubToken, SupabaseToken, AzureAccessToken, ...
```
Read a specific key:
``` powershell
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -Key GithubToken -Raw
```
> `-Raw` prints the exact string. Without `-Raw`, JSON values (like
> `SupabaseToken`) are pretty-printed.
------------------------------------------------------------------------
## 4) Edit a value
You have **two ways** to edit:
### Option A (recommended): *dot-source* once, then call `Set-StoreValue`
Dot-sourcing loads the helper functions into your shell:
``` powershell
. "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1"
```
Now update a key:
- **Plain string key** (e.g., `GithubToken`):
``` powershell
Set-StoreValue -UserId "<userId>" -Key "GithubToken" -Value "ghp_or_ghu_yourNewTokenHere"
```
- **JSON key** (e.g., `SupabaseToken` expects JSON):
``` powershell
$newPat = '{"AccessToken":"myNewSupabasePAT","RefreshToken":null,"ExpiresAt":"2025-12-31T23:59:59Z"}'
Set-StoreValue -UserId "<userId>" -Key "SupabaseToken" -Value $newPat
```
Verify:
``` powershell
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -Key GithubToken -Raw
# or
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -Key SupabaseToken
```
### Option B: stay "no functions" and only run the script
Use this only to **view** or **list**; editing requires Option A.
------------------------------------------------------------------------
## 5) Common pitfalls & fixes
- **`The term 'Set-StoreValue' is not recognized`**\
You *ran* the script but didn't dot-source it. Dot-source first:
``` powershell
. "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1"
```
- **`Unable to find type [System.Security.Cryptography.ProtectedData]`**\
Use the script Jimmy provided (it includes
`Add-Type -AssemblyName System.Security`).\
If you still see it:
``` powershell
Add-Type -AssemblyName System.Security
```
- **`DPAPI Unprotect failed...`**\
You're not running as the same Windows user that created the file.
Switch to that user profile.
- **`%AppData%` doesn't work in PowerShell**\
Use `$env:APPDATA` (PowerShell style):
``` powershell
cd "$env:APPDATA\rIDE\<userId>"
```
- **Edited value shape**
- Keys like `GithubToken` are **plain strings**.\
- Keys like `SupabaseToken` and `projectSecret_*` are **JSON**.
Make sure you pass valid JSON.
------------------------------------------------------------------------
## 6) Quick examples (ready to paste)
### List keys
``` powershell
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -ListKeys
```
### Read GitHub token (raw)
``` powershell
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -Key GithubToken -Raw
```
### Update GitHub token
``` powershell
. "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1"
Set-StoreValue -UserId "<userId>" -Key "GithubToken" -Value "ghp_or_ghu_yourNewTokenHere"
```
### Update Supabase token (JSON)
``` powershell
. "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1"
$newPat = '{"AccessToken":"myNewSupabasePAT","RefreshToken":null,"ExpiresAt":"2025-12-31T23:59:59Z"}'
Set-StoreValue -UserId "<userId>" -Key "SupabaseToken" -Value $newPat
```
### Verify
``` powershell
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -Key GithubToken -Raw
& "C:\Users\<you>\OneDrive\Desktop\Codebuddy\decrypt-dat-file.ps1" -UserId "<userId>" -Key SupabaseToken
```

View File

@@ -0,0 +1,196 @@
<#
.SYNOPSIS
Decrypts and edits rIDE SecureLocalStorage store.dat (DPAPI CurrentUser).
Works on Windows PowerShell 5.1 and PowerShell 7+.
.PARAMETER UserId
The userId subfolder under %AppData%\rIDE\. Use "." with -AppDataOverride "." if you're already in the folder.
.PARAMETER Key
Optional. If provided, prints only this key's value.
.PARAMETER ListKeys
Optional. If set, prints only the available keys.
.PARAMETER AppDataOverride
Optional. Override base AppData path (defaults to [Environment]::GetFolderPath("ApplicationData")).
Example: -AppDataOverride "." to use .\store.dat in the current directory.
.PARAMETER Raw
Optional. Output raw strings (no pretty objects / nested JSON parsing).
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$UserId,
[string]$Key,
[switch]$ListKeys,
[string]$AppDataOverride,
[switch]$Raw
)
# Ensure DPAPI types exist
Add-Type -AssemblyName System.Security
# ---- Helpers ----
# Convert PSObject/arrays into pure hashtables/arrays so PS 5.1 works like PS7 -AsHashtable
function Convert-PSObjectToHashtable {
param([Parameter(ValueFromPipeline=$true)]$InputObject)
process {
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IDictionary]) {
$ht = @{}
foreach ($k in $InputObject.Keys) {
$ht[$k] = Convert-PSObjectToHashtable $InputObject[$k]
}
return $ht
}
if ($InputObject -is [System.Collections.IEnumerable] -and -not ($InputObject -is [string])) {
$arr = @()
foreach ($item in $InputObject) { $arr += ,(Convert-PSObjectToHashtable $item) }
return $arr
}
if ($InputObject -is [psobject]) {
$ht = @{}
foreach ($p in $InputObject.PSObject.Properties) {
$ht[$p.Name] = Convert-PSObjectToHashtable $p.Value
}
return $ht
}
return $InputObject
}
}
function Get-StorePath {
param([string]$UserId, [string]$AppDataOverride)
$appData = if ($AppDataOverride) { $AppDataOverride } else { [Environment]::GetFolderPath("ApplicationData") }
# Code uses "rIDE" but Windows is case-insensitive
$dir = Join-Path (Join-Path $appData "rIDE") $UserId
return Join-Path $dir "store.dat"
}
function Read-DecryptedStore {
param([string]$Path)
if (-not (Test-Path -LiteralPath $Path)) { throw "File not found: $Path" }
try {
$encBytes = [System.IO.File]::ReadAllBytes($Path)
} catch {
throw "Unable to read file '$Path': $($_.Exception.Message)"
}
try {
$decBytes = [System.Security.Cryptography.ProtectedData]::Unprotect(
$encBytes, $null,
[System.Security.Cryptography.DataProtectionScope]::CurrentUser
)
} catch {
throw "DPAPI Unprotect failed. Are you running as the SAME Windows user that created the file? Inner: $($_.Exception.Message)"
}
$json = [System.Text.Encoding]::UTF8.GetString($decBytes)
try {
$obj = $json | ConvertFrom-Json
$dict = Convert-PSObjectToHashtable $obj # PS5.1-safe
if ($dict -isnot [hashtable]) { throw "Expected a JSON object/dictionary at the top level." }
return $dict
} catch {
throw "Decrypted bytes were not valid JSON: $($_.Exception.Message)"
}
}
function Try-ParseJson {
param([string]$s)
try {
if ($null -ne $s -and ($s.TrimStart().StartsWith('{') -or $s.TrimStart().StartsWith('['))) {
return $s | ConvertFrom-Json
}
} catch { }
return $s
}
function Write-EncryptedStore {
param(
[string]$Path,
[hashtable]$Store
)
$json = $Store | ConvertTo-Json -Depth 10 -Compress
$bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
$enc = [System.Security.Cryptography.ProtectedData]::Protect(
$bytes, $null,
[System.Security.Cryptography.DataProtectionScope]::CurrentUser
)
[System.IO.File]::WriteAllBytes($Path, $enc)
}
function Set-StoreValue {
param(
[string]$UserId,
[string]$Key,
[string]$Value,
[string]$AppDataOverride
)
$path = Get-StorePath -UserId $UserId -AppDataOverride $AppDataOverride
$store = Read-DecryptedStore -Path $path
$store[$Key] = $Value
Write-EncryptedStore -Path $path -Store $store
Write-Host "Key '$Key' updated successfully in $path"
}
# ---- Main (print/list/single-key) ----
$path = Get-StorePath -UserId $UserId -AppDataOverride $AppDataOverride
try {
$store = Read-DecryptedStore -Path $path
} catch {
Write-Error $_.Exception.Message
exit 1
}
if ($ListKeys) {
$store.Keys | Sort-Object
exit 0
}
if ($Key) {
if ($store.ContainsKey($Key)) {
$val = $store[$Key]
if ($Raw) {
$val
} else {
$parsed = Try-ParseJson -s $val
$parsed | ConvertTo-Json -Depth 10
}
exit 0
} else {
Write-Error "Key '$Key' not found. Use -ListKeys to see available keys."
exit 2
}
}
# No key specified: show entire dictionary (pretty where possible)
if ($Raw) {
$store.GetEnumerator() | Sort-Object Name | ForEach-Object {
"{0} = {1}" -f $_.Key, $_.Value
}
} else {
$pretty = @{}
foreach ($k in $store.Keys) { $pretty[$k] = Try-ParseJson -s $store[$k] }
$pretty | ConvertTo-Json -Depth 10
}