Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5f24323
ci(release): drop setup-dotnet cache without packages.lock.json (#992)
justcoding121 Aug 30, 2026
18ea46b
fix: repair long-run MITM cert handles and quiet expected proxy noise…
justcoding121 Aug 30, 2026
21d518b
Update README.md
justcoding121 Aug 30, 2026
01c1212
Inspector FIFO session cache
justcoding121 Aug 30, 2026
a3a7146
feat(inspector): expose Capture retention, logging, and HTTPS host se…
justcoding121 Aug 30, 2026
0080a44
fix: pin product version back to 7.0.0 for the beta cut
justcoding121 Aug 30, 2026
f818c47
feat(inspector): Options menu, plain-language UI, ignore-cert default on
justcoding121 Aug 30, 2026
bb81d5e
feat(inspector): default cert validation on; add settings-only factor…
justcoding121 Aug 30, 2026
298be1d
fix: harden origin parse, IPv6 soft-skip, ALPN, and Inspector CA hygiene
justcoding121 Aug 31, 2026
9226f22
fix: avoid Trusted Root yes/no prompts on re-trust
justcoding121 Aug 31, 2026
657c231
ux(inspector): rename Rotate root CA to Clear and reinstall
justcoding121 Aug 31, 2026
de8e189
fix: green UI/Plus tests and bump product to 7.0.1 for beta cut
justcoding121 Aug 31, 2026
611633e
fix(inspector): set HAR export StatusText without UI marshal flake
justcoding121 Aug 31, 2026
a20ca1c
fix(inspector): keep HAR export on UI sync context for headless
justcoding121 Aug 31, 2026
aaf9ed3
fix(inspector): write HAR export synchronously for headless StatusText
justcoding121 Aug 31, 2026
f9fcb63
fix(tests): lengthen IPv6 soft-skip TTL expiry assert for CI
justcoding121 Aug 31, 2026
4bdce39
fix: reject cleartext h2c preface when EnableHttp2 is false
justcoding121 Aug 31, 2026
2dada86
fix: clear Sonar PR bugs/smells and lift new-code coverage
justcoding121 Aug 31, 2026
e4857ca
fix: close remaining Sonar smells and cover rotate/CA cache paths
justcoding121 Aug 31, 2026
a85a9e3
fix(tests): load cert bytes via X509CertificateLoader under WarnAsError
justcoding121 Aug 31, 2026
dc32dc9
test: cover RotateCa install path and CurrentUser cert cleanup
justcoding121 Aug 31, 2026
d0e889c
test: cover InstallCertificate reuse, ALPN HResult, elevate/loopback …
justcoding121 Aug 31, 2026
c63cf7d
fix(e2e): retry transient Headless IFontManagerImpl races on wait
justcoding121 Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ jobs:
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
cache: true
- name: Test
run: |
dotnet test src/Titanium.Web.Proxy.sln -c Release --nologo --filter "TestCategory!=Slow&TestCategory!=E2E-UI-Window"
Expand Down Expand Up @@ -98,7 +97,6 @@ jobs:
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
cache: true
- uses: actions/cache@v4
with:
path: tools/packaging/.cache/http3-natives
Expand Down Expand Up @@ -138,7 +136,6 @@ jobs:
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
cache: true
- name: Build Plus
env:
RELEASE_TAG: ${{ needs.resolve-version.outputs.release_tag }}
Expand Down Expand Up @@ -185,7 +182,6 @@ jobs:
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
cache: true
- uses: actions/cache@v4
with:
path: tools/packaging/.cache/http3-natives
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ A lightweight, high-performance HTTP(S) proxy — reverse / edge CLI, desktop In

| Product | What it is | How you get it |
|---------|------------|----------------|
| **Titanium.Cli** (`titanium` / `twp`) | Standalone reverse / edge proxy for any stack: `run`, `test`, `version`, `update` | GitHub Releases, winget, or `dotnet tool` |
| **Titanium Inspector** | Desktop MITM debugger (session grid, inspectors, AutoResponder, breakpoints, HAR) | Windows MSI, winget, or GitHub Releases |
| **Titanium.Plus** | Optional advanced features: control plane, ops, observability, and dashboard | `titanium update --plus` |
| **Titanium.Web.Proxy** | Core library. Embed a MITM and/or reverse proxy in a .NET app | NuGet |
| **Titanium.Cli** (`titanium` / `twp`) | Standalone reverse / edge proxy for any stack: `run`, `test`, `version`, `update` | [Download (Windows, Linux & Mac)](https://titaniumproxy.com/download#cli) |
| **Titanium Inspector** | Desktop MITM debugger (session grid, inspectors, AutoResponder, breakpoints, HAR) | [Download (Windows, Linux & Mac)](https://titaniumproxy.com/download#inspector) |
| **Titanium.Plus** | Optional advanced features: control plane, ops, observability, and dashboard | After installing CLI, run `titanium update --plus` |
| **Titanium.Web.Proxy** | Core library. Embed a MITM and/or reverse proxy in a .NET app | [NuGet](https://www.nuget.org/packages/Titanium.Web.Proxy/7.0.1-beta) (`dotnet add package Titanium.Web.Proxy --prerelease`) |

CLI and Plus target reverse-proxy / edge workloads (routing, load balancing, health, discovery) on Windows, Linux, and macOS. Inspector is the MITM debugging product. The Core library is the embed path for .NET. Requires .NET 10 or later.

Expand All @@ -67,7 +67,7 @@ On Windows, **winget is stable-only**:
winget install justcoding121.TitaniumCli
```

For **beta**, download self-contained zips from [Download](https://titaniumproxy.com/download) / [GitHub Releases](https://github.com/justcoding121/titanium-web-proxy/releases) when a product release includes `Titanium.Cli-*.zip` assets (e.g. `v7.0.0-beta`). Extract and run:
For **beta**, download self-contained zips from [Download](https://titaniumproxy.com/download) / [GitHub Releases](https://github.com/justcoding121/titanium-web-proxy/releases) when a product release includes `Titanium.Cli-*.zip` assets (e.g. `v7.0.1-beta`). Extract and run:

```shell
titanium run -c twp.yaml
Expand All @@ -82,7 +82,7 @@ Optional Plus: run `titanium update --plus` (add `--channel beta` for prerelease

### Titanium Inspector

Prefer [Download](https://titaniumproxy.com/download). On Windows, winget id `justcoding121.TitaniumInspector` is **stable-only**; MSI / portable zip for beta come from the product `v*` release (e.g. `v7.0.0-beta`). Start interception from the Capture menu, install the root CA, then toggle system proxy.
Prefer [Download](https://titaniumproxy.com/download). On Windows, winget id `justcoding121.TitaniumInspector` is **stable-only**; MSI / portable zip for beta come from the product `v*` release (e.g. `v7.0.1-beta`). Start interception from the Capture menu, install the root CA, then toggle system proxy.

## Quick start

Expand Down
2 changes: 1 addition & 1 deletion src/Titanium.Cli/Titanium.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<SignAssembly>false</SignAssembly>
<VersionPrefix>7.0.0</VersionPrefix>
<VersionPrefix>7.0.1</VersionPrefix>
<Authors>Jehonathan Thomas</Authors>
<Description>Titanium Web Proxy CLI (titanium / twp).</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
4 changes: 2 additions & 2 deletions src/Titanium.Inspector/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public partial class App : Application
public override void OnFrameworkInitializationCompleted()
{
var settings = SettingsService.Load();
var sessions = new SessionRegistry();
var buffer = new SessionStreamBuffer(sessions);
var sessions = new SessionRegistry(SessionStoreOptions.FromSettings(settings.Current));
var buffer = new SessionStreamBuffer();
var updates = new UpdateService(settings);
PlusInspectorLoader.TryLoadPanels(out _);

Expand Down
54 changes: 51 additions & 3 deletions src/Titanium.Inspector/Services/IInspectorDialogs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,43 @@ public interface IInspectorDialogs
/// Show device CA setup steps. Returns true if the user chose Export CA; false on Close / no owner.
/// </summary>
Task<bool> ShowDeviceCaSetupAsync(Window? owner, string message);

/// <summary>Ask to clear and reinstall (regenerate) the Titanium root CA. Returns true if confirmed.</summary>
Task<bool> ConfirmRotateRootCaAsync(Window? owner);

/// <summary>
/// Confirm resetting Inspector preferences to factory defaults (not the root CA or sessions).
/// </summary>
Task<bool> ConfirmResetSettingsAsync(Window? owner);
}

/// <summary>Avalonia modal dialogs.</summary>
public sealed class AvaloniaInspectorDialogs : IInspectorDialogs
{
private const string CancelLabel = "Cancel";
public Task<bool> ConfirmInstallRootCaAsync(Window? owner) =>
SimpleConfirmDialog.ShowAsync(
owner,
"Install root CA",
"Decrypt HTTPS requires trusting the Titanium Inspector root CA in your current-user certificate store (and Keychain/NSS on macOS/Linux). Install now?",
accept: "Install",
cancel: "Cancel");
cancel: CancelLabel);

public Task<bool> ConfirmRemoveRootCaAsync(Window? owner) =>
SimpleConfirmDialog.ShowAsync(
owner,
"Remove root CA",
"Remove the Titanium Inspector root CA from the current-user Trusted Root store? HTTPS decrypt will be turned off.",
accept: "Remove",
cancel: "Cancel");
cancel: CancelLabel);

public Task<bool> ConfirmElevateRootCaAsync(Window? owner) =>
SimpleConfirmDialog.ShowAsync(
owner,
"Install with administrator privileges",
"User-level trust failed or was insufficient. Continue to show the OS admin prompt (UAC / macOS authentication / polkit)? Cancel leaves certificate settings unchanged.",
accept: "Continue",
cancel: "Cancel");
cancel: CancelLabel);

public Task<bool> ShowDeviceCaSetupAsync(Window? owner, string message) =>
SimpleConfirmDialog.ShowAsync(
Expand All @@ -56,6 +65,29 @@ public Task<bool> ShowDeviceCaSetupAsync(Window? owner, string message) =>
accept: "Export CA",
cancel: "Close",
height: 320);

public Task<bool> ConfirmRotateRootCaAsync(Window? owner) =>
SimpleConfirmDialog.ShowAsync(
owner,
"Clear and reinstall root CA",
"Clear the current Titanium Inspector root CA and create a new one?\n\n" +
"• All same-name Titanium roots are removed from the current-user Trusted Root store\n" +
"• Cached site certificates for this install are cleared\n" +
"• You will be asked to trust the new root CA again (or enable Decrypt HTTPS)\n\n" +
"Stop capture is recommended first.",
accept: "Clear and reinstall",
cancel: CancelLabel,
height: 320);

public Task<bool> ConfirmResetSettingsAsync(Window? owner) =>
SimpleConfirmDialog.ShowAsync(
owner,
"Reset Inspector settings",
"Restore bind address, menus, Tools (Composer/Breakpoints/AutoResponder/Scripts), retention, logging, HTTPS host lists, and layout to factory defaults?\n\n" +
"This does not remove the root CA, change OS trust, clear captured sessions, or delete the on-disk body cache. Restart Inspector afterward so retention limits fully apply.",
accept: "Reset settings",
cancel: CancelLabel,
height: 300);
}

/// <summary>Scripted answers for unit / E2E-UI tests (no real windows).</summary>
Expand All @@ -65,10 +97,14 @@ public sealed class ScriptedInspectorDialogs : IInspectorDialogs
public bool RemoveRootCaResult { get; set; } = true;
public bool ElevateRootCaResult { get; set; } = true;
public bool DeviceCaSetupResult { get; set; }
public bool ResetSettingsResult { get; set; } = true;
public bool RotateRootCaResult { get; set; } = true;
public int InstallRootCaCalls { get; private set; }
public int RemoveRootCaCalls { get; private set; }
public int ElevateRootCaCalls { get; private set; }
public int DeviceCaSetupCalls { get; private set; }
public int ResetSettingsCalls { get; private set; }
public int RotateRootCaCalls { get; private set; }
public string? LastDeviceCaSetupMessage { get; private set; }

public Task<bool> ConfirmInstallRootCaAsync(Window? owner)
Expand All @@ -89,10 +125,22 @@ public Task<bool> ConfirmElevateRootCaAsync(Window? owner)
return Task.FromResult(ElevateRootCaResult);
}

public Task<bool> ConfirmRotateRootCaAsync(Window? owner)
{
RotateRootCaCalls++;
return Task.FromResult(RotateRootCaResult);
}

public Task<bool> ShowDeviceCaSetupAsync(Window? owner, string message)
{
DeviceCaSetupCalls++;
LastDeviceCaSetupMessage = message;
return Task.FromResult(DeviceCaSetupResult);
}

public Task<bool> ConfirmResetSettingsAsync(Window? owner)
{
ResetSettingsCalls++;
return Task.FromResult(ResetSettingsResult);
}
}
Loading
Loading