diff --git a/src/ProtonVPN.Api/Installers/ApiModule.cs b/src/ProtonVPN.Api/Installers/ApiModule.cs new file mode 100644 index 000000000..997ae1dbe --- /dev/null +++ b/src/ProtonVPN.Api/Installers/ApiModule.cs @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023 Proton AG + * Extended to support unified Proton Suite (VPN, Mail, Drive, Pass) + */ + +using Autofac; +using ProtonVPN.Api.Contracts; +using ProtonVPN.Api.Contracts.Mail; +using ProtonVPN.Api.Contracts.Drive; +using ProtonVPN.Api.Contracts.Pass; +using ProtonVPN.Api.Deserializers; +using ProtonVPN.Api.Handlers; +using ProtonVPN.Api.Handlers.Retries; +using ProtonVPN.Api.Handlers.TlsPinning; +using ProtonVPN.Common.Legacy.OS.Net.Http; + +namespace ProtonVPN.Api.Installers +{ + public class ApiModule : Module + { + protected override void Load(ContainerBuilder builder) + { + // ── Shared infrastructure ────────────────────────────── + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + + builder.RegisterType().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + + // ── Report client (cached) ───────────────────────────── + builder.Register(c => + new CachingReportClient( + new ReportClient(c.Resolve()))) + .As() + .SingleInstance(); + + // ── Per-app API clients ──────────────────────────────── + RegisterAppClients(builder); + + // ── HTTP handlers ────────────────────────────────────── + RegisterHandlers(builder); + + // ── Per-app HTTP client factories ────────────────────── + RegisterAppHttpClientFactories(builder); + } + + // ── NEW: Register one API client per Proton app ──────────── + private void RegisterAppClients(ContainerBuilder builder) + { + // Proton VPN (existing) + builder.RegisterType() + .As() + .SingleInstance(); + + // Proton Mail + builder.RegisterType() + .As() + .SingleInstance(); + + // Proton Drive + builder.RegisterType() + .As() + .SingleInstance(); + + // Proton Pass + builder.RegisterType() + .As() + .SingleInstance(); + } + + // ── NEW: Separate HTTP client factories per app ──────────── + private void RegisterAppHttpClientFactories(ContainerBuilder builder) + { + // VPN (existing) + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + builder.RegisterType() + .AsImplementedInterfaces().SingleInstance(); + + // Mail, Drive, Pass get their own factories + // so their traffic is isolated and identifiable + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + builder.RegisterType() + .As().SingleInstance(); + } + + // ── Existing: HTTP handler stack ─────────────────────────── + // Each app gets its own handler instances (InstancePerDependency) + // so their retry/logging stacks don't interfere with each other + private void RegisterHandlers(ContainerBuilder builder) + { + builder.RegisterType() + .As().AsSelf().InstancePerDependency(); + builder.RegisterType() + .As().AsSelf().InstancePerDependency(); + builder.RegisterType() + .As().AsSelf().InstancePerDependency(); + builder.RegisterType() + .As().AsSelf().InstancePerDependency(); + + builder.RegisterType() + .AsImplementedInterfaces().AsSelf().InstancePerDependency(); + builder.RegisterType().InstancePerDependency(); + builder.RegisterType().InstancePerDependency(); + builder.RegisterType().InstancePerDependency(); + builder.RegisterType().InstancePerDependency(); + builder.RegisterType().InstancePerDependency(); + } + } +} \ No newline at end of file