├── .gitattributes ├── src ├── WHMapper │ ├── wwwroot │ │ ├── favicon.ico │ │ ├── Images │ │ │ ├── logo_anoik.png │ │ │ ├── logo_dotlan.png │ │ │ ├── splashscreen.png │ │ │ └── logo_zkillboard.png │ │ └── WHMapper.lib.module.js │ ├── Models │ │ ├── DTO │ │ │ ├── ResponseMessage │ │ │ │ ├── IResponseMessage.cs │ │ │ │ ├── SuccessMessage.cs │ │ │ │ └── ErrorMessage.cs │ │ │ ├── ClientUID.cs │ │ │ ├── EveAPI │ │ │ │ ├── Route │ │ │ │ │ └── Enums │ │ │ │ │ │ └── RouteType.cs │ │ │ │ ├── Search │ │ │ │ │ ├── SearchCharacterResults.cs │ │ │ │ │ ├── SearchAllianceResults.cs │ │ │ │ │ └── SearchCoporationResults.cs │ │ │ │ ├── Assets │ │ │ │ │ └── AssetName.cs │ │ │ │ ├── Location │ │ │ │ │ ├── Ship.cs │ │ │ │ │ ├── Activity.cs │ │ │ │ │ └── EveLocation.cs │ │ │ │ ├── Position.cs │ │ │ │ ├── Character │ │ │ │ │ ├── Portrait.cs │ │ │ │ │ └── Character.cs │ │ │ │ ├── Universe │ │ │ │ │ ├── Region.cs │ │ │ │ │ ├── Constellation.cs │ │ │ │ │ ├── Category.cs │ │ │ │ │ ├── Group.cs │ │ │ │ │ ├── Star.cs │ │ │ │ │ ├── Stargate.cs │ │ │ │ │ ├── Planet.cs │ │ │ │ │ └── ESISolarSystem.cs │ │ │ │ ├── SSO │ │ │ │ │ └── EveToken.cs │ │ │ │ ├── Alliance │ │ │ │ │ └── Alliance.cs │ │ │ │ ├── Dogma │ │ │ │ │ └── Attribute.cs │ │ │ │ └── Corporation │ │ │ │ │ └── Corporation.cs │ │ │ ├── EveMapper │ │ │ │ ├── Enums │ │ │ │ │ ├── WHAnalizedSignatureEnums.cs │ │ │ │ │ ├── EveEntityEnums.cs │ │ │ │ │ ├── WHEffectEnums.cs │ │ │ │ │ └── EveSystemTypeEnums.cs │ │ │ │ ├── EveSystemEffect.cs │ │ │ │ ├── WHMapperUser.cs │ │ │ │ ├── EveEntity │ │ │ │ │ ├── SunEntity.cs │ │ │ │ │ ├── AEveEntity.cs │ │ │ │ │ ├── AllianceEntity.cs │ │ │ │ │ ├── CharactereEntity.cs │ │ │ │ │ ├── CorporationEntity.cs │ │ │ │ │ ├── ShipEntity.cs │ │ │ │ │ ├── RegionEntity.cs │ │ │ │ │ ├── GroupEntity.cs │ │ │ │ │ ├── StargateEntity.cs │ │ │ │ │ ├── ConstellationEntity.cs │ │ │ │ │ ├── SystemEntity.cs │ │ │ │ │ └── WHEntity.cs │ │ │ │ ├── WHAnalizedSignature.cs │ │ │ │ ├── EveRoute.cs │ │ │ │ └── WormholeType.cs │ │ │ ├── SDE │ │ │ │ ├── SDEStargate.cs │ │ │ │ ├── SDESecondarySun.cs │ │ │ │ ├── SolarSystem.cs │ │ │ │ └── SolarSystemJump.cs │ │ │ ├── UserToken.cs │ │ │ ├── MapAdmin │ │ │ │ └── MapAdmin.cs │ │ │ ├── RoutePlanner │ │ │ │ └── RouteConnection.cs │ │ │ └── Anoik │ │ │ │ └── WormholeTypeInfo.cs │ │ └── Db │ │ │ ├── Enums │ │ │ ├── WHAccessEnums.cs │ │ │ ├── SystemLinkEOLStatus.cs │ │ │ ├── WHSystemStatusEnums.cs │ │ │ ├── WHSignatureEnums.cs │ │ │ └── WHSystemLinkEnums.cs │ │ │ ├── WHAdmin.cs │ │ │ ├── WHMap.cs │ │ │ ├── WHRoute.cs │ │ │ ├── WHAccess.cs │ │ │ ├── WHJumpLog.cs │ │ │ ├── WHNote.cs │ │ │ └── WHSystemLink.cs │ ├── Services │ │ ├── EveAPI │ │ │ ├── RequestSecurity.cs │ │ │ ├── RequestMethod.cs │ │ │ ├── EveAPIServiceConstants.cs │ │ │ ├── Corporations │ │ │ │ ├── ICorporationServices.cs │ │ │ │ └── CorporationServices.cs │ │ │ ├── User Interface │ │ │ │ ├── IUserInterfaceServices.cs │ │ │ │ └── UserInterfaceServices.cs │ │ │ ├── Locations │ │ │ │ ├── ILocationServices.cs │ │ │ │ └── LocationServices.cs │ │ │ ├── Alliances │ │ │ │ ├── IAllianceServices.cs │ │ │ │ └── AllianceServices.cs │ │ │ ├── Characters │ │ │ │ ├── ICharacterServices.cs │ │ │ │ └── CharacterServices.cs │ │ │ ├── Assets │ │ │ │ ├── IAssetsServices.cs │ │ │ │ └── AssetsServices.cs │ │ │ ├── Dogma │ │ │ │ ├── IDogmaServices.cs │ │ │ │ └── DogmaServices.cs │ │ │ ├── Search │ │ │ │ ├── ISearchServices.cs │ │ │ │ └── SearchServices.cs │ │ │ ├── Routes │ │ │ │ └── IRouteServices.cs │ │ │ ├── Universe │ │ │ │ └── IUniverseServices.cs │ │ │ ├── IEveAPIServices.cs │ │ │ └── EveOnlineAccessTokenHandler.cs │ │ ├── Paste │ │ │ ├── IPasteServices.cs │ │ │ └── PasteServices.cs │ │ ├── BrowserClientIdProvider │ │ │ ├── IBrowserClientIdProvider.cs │ │ │ ├── Extension │ │ │ │ └── BrowserClientIdCookieMiddleware.cs │ │ │ └── BrowserClientIdProvider.cs │ │ ├── SDE │ │ │ ├── ISDEDataSupplier.cs │ │ │ ├── SDEConstants.cs │ │ │ ├── ISDEServiceManager.cs │ │ │ ├── ISDEService.cs │ │ │ └── SdeDataSupplier.cs │ │ ├── EveOAuthProvider │ │ │ ├── Validators │ │ │ │ ├── IEveOnlineAccessTokenValidator.cs │ │ │ │ └── EveOnlineAccessTokenValidator.cs │ │ │ ├── Services │ │ │ │ ├── IEveUserInfosServices.cs │ │ │ │ ├── IClaimServices.cs │ │ │ │ ├── IEveOnlineTokenProvider.cs │ │ │ │ └── EveUserInfosServices.cs │ │ │ ├── EVEOnlinePostConfigureOptions.cs │ │ │ ├── EVEOnlineAuthenticationOptions.cs │ │ │ └── EVEOnlineAuthenticationDefaults.cs │ │ ├── EveScoutAPI │ │ │ ├── EveScoutAPIServiceConstants.cs │ │ │ ├── IEveScoutAPIServices.cs │ │ │ └── EveScoutAPIServices.cs │ │ ├── Anoik │ │ │ ├── IAnoikDataSupplier.cs │ │ │ ├── IAnoikServices.cs │ │ │ └── AnoikJsonDataSupplier.cs │ │ ├── Cache │ │ │ └── ICacheService.cs │ │ ├── EveMapper │ │ │ ├── AuthorizationPolicies │ │ │ │ ├── EveMapperMapRequirement.cs │ │ │ │ ├── EveMapperAdminRequirement.cs │ │ │ │ ├── EveMapperAccessRequirement.cs │ │ │ │ ├── EveMapperAdminHandler.cs │ │ │ │ ├── EveMapperAccessHandler.cs │ │ │ │ └── EveMapperMapHandler.cs │ │ │ ├── IEveMapperAccessHelper.cs │ │ │ ├── IEveMapperTracker.cs │ │ │ ├── IEveMapperUserManagementService.cs │ │ │ ├── IEveMapperService.cs │ │ │ ├── IEveMapperHelper.cs │ │ │ ├── IEveMapperSearch.cs │ │ │ ├── IEveMapperCacheService.cs │ │ │ └── IEveMapperRoutePlannerHelper.cs │ │ ├── EveJwTExtensions │ │ │ └── EveOnlineJwkDefaults.cs │ │ ├── WHColor │ │ │ └── IWHColorHelper.cs │ │ ├── WHSignatures │ │ │ └── IWHSignatureHelper.cs │ │ └── EveCookieExtensions │ │ │ └── EveCookieServiceCollectionExtensions.cs │ ├── Repositories │ │ ├── WHAdmins │ │ │ └── IWHAdminRepository.cs │ │ ├── WHAccesses │ │ │ └── IWHAccessRepository.cs │ │ ├── WHJumpLogs │ │ │ └── IWHJumpLogRepository.cs │ │ ├── WHSystemLinks │ │ │ └── IWHSystemLinkRepository.cs │ │ ├── WHNotes │ │ │ └── IWHNoteRepository.cs │ │ ├── WHSystems │ │ │ └── IWHSystemRepository.cs │ │ ├── WHRoutes │ │ │ └── IWHRouteRepository.cs │ │ ├── IDefaultRepository.cs │ │ ├── WHMaps │ │ │ └── IWHMapRepository.cs │ │ ├── WHSignatures │ │ │ └── IWHSignatureRepository.cs │ │ └── ADefaultRepository.cs │ ├── RedirectToLogin.razor │ ├── Properties │ │ └── launchSettings.json │ ├── Components │ │ ├── Pages │ │ │ ├── Mapper │ │ │ │ ├── Notes │ │ │ │ │ └── Overview.razor │ │ │ │ ├── RoutePlanner │ │ │ │ │ ├── Delete.razor │ │ │ │ │ └── Delete.razor.cs │ │ │ │ ├── Administration │ │ │ │ │ ├── Map │ │ │ │ │ │ ├── Add.razor │ │ │ │ │ │ ├── Delete.razor │ │ │ │ │ │ ├── RemoveAccess.razor │ │ │ │ │ │ ├── AddAccess.razor │ │ │ │ │ │ └── Add.razor.cs │ │ │ │ │ └── Access │ │ │ │ │ │ └── Delete.razor │ │ │ │ ├── Signatures │ │ │ │ │ ├── Delete.razor │ │ │ │ │ └── Import.razor │ │ │ │ ├── CustomNode │ │ │ │ │ └── EveSystemLink.razor.cs │ │ │ │ ├── Search │ │ │ │ │ └── SearchSystem.razor │ │ │ │ ├── CustomDiagramSelectionBehavior.cs │ │ │ │ ├── Users │ │ │ │ │ └── Overview.razor │ │ │ │ └── Overview.razor │ │ │ └── Error.razor │ │ ├── Routes.razor │ │ ├── _Imports.razor │ │ ├── App.razor │ │ └── Layout │ │ │ └── MainLayout.razor.css │ ├── EventHandler.cs │ ├── Migrations │ │ ├── 20231204092305_AddSystemStatusToWHNote.cs │ │ ├── 20250626204448_Add_WHSystem_AlternateName.cs │ │ ├── 20231003084350_AddWHNote.cs │ │ ├── 20251215_ReplaceIsEOLWithEOLStatus.cs │ │ ├── 20231225204239_Route db for planner.cs │ │ ├── 20240828145305_Allow_Multi_Map.cs │ │ ├── 20240909201955_Update_Notes_To_Be_Unique_For_Multi_Map.cs │ │ └── 20240912202232_Update_Route_To_Be_Unique_For_Multi_Map.cs │ ├── Dockerfile │ ├── Hubs │ │ ├── ConnectionMapping.cs │ │ └── IWHMapperNotificationHub.cs │ └── appsettings.json ├── WHMapper.Tests │ ├── Usings.cs │ ├── InlineAutoMoqDataAttribute.cs │ ├── DomainCustomization.cs │ ├── AutoDomainDataAttribute.cs │ ├── AutoMoqDataAttribute.cs │ ├── DisplayNameOrderer.cs │ ├── Services │ │ ├── Cache │ │ │ └── FakeCacheObject.cs │ │ └── Anoik │ │ │ └── AnoikServiceTestConstants.cs │ ├── appsettings.json │ └── Models │ │ ├── UserTokenTest.cs │ │ ├── ClientUIDTest.cs │ │ └── MapAdminTests.cs └── WHMapper.sln ├── .github ├── dependabot.yml ├── release.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── .vscode └── settings.json ├── deploy ├── docker │ ├── haproxy │ │ ├── nginx │ │ │ └── nginx.conf │ │ └── docker-compose.yml │ ├── stop.sh │ ├── start.sh │ ├── eve-whmapper │ │ └── docker-compose.yml │ ├── start.ps1 │ ├── stop.ps1 │ └── renew-certificates.sh ├── kubernetes │ └── deploys │ │ ├── ingress.yaml │ │ ├── frontend.yaml │ │ ├── envs.yaml │ │ ├── base.yaml │ │ └── backend.yaml └── localhost │ └── docker │ ├── start.ps1 │ ├── stop.ps1 │ ├── docker-compose.yml │ └── README.MD ├── .clabot ├── LICENSE └── CONTRIBUTING.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.zip filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /src/WHMapper/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pfh59/eve-whmapper/HEAD/src/WHMapper/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/WHMapper/wwwroot/Images/logo_anoik.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pfh59/eve-whmapper/HEAD/src/WHMapper/wwwroot/Images/logo_anoik.png -------------------------------------------------------------------------------- /src/WHMapper/wwwroot/Images/logo_dotlan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pfh59/eve-whmapper/HEAD/src/WHMapper/wwwroot/Images/logo_dotlan.png -------------------------------------------------------------------------------- /src/WHMapper/wwwroot/Images/splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pfh59/eve-whmapper/HEAD/src/WHMapper/wwwroot/Images/splashscreen.png -------------------------------------------------------------------------------- /src/WHMapper/wwwroot/Images/logo_zkillboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pfh59/eve-whmapper/HEAD/src/WHMapper/wwwroot/Images/logo_zkillboard.png -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "nuget" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "sonarlint.connectedMode.project": { 3 | "connectionId": "vscode", 4 | "projectKey": "pfh59_eve-whmapper" 5 | } 6 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/ResponseMessage/IResponseMessage.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.ResponseMessage 2 | { 3 | public interface IResponseMessage 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/RequestSecurity.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveAPI 2 | { 3 | public enum RequestSecurity 4 | { 5 | Public, 6 | Authenticated 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/ClientUID.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WHMapper.Models.DTO; 4 | 5 | public class ClientUID 6 | { 7 | public string? ClientId { get; set; } = string.Empty; 8 | } 9 | -------------------------------------------------------------------------------- /src/WHMapper/Services/Paste/IPasteServices.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper; 2 | 3 | public interface IPasteServices 4 | { 5 | event Func Pasted; 6 | Task Paste(string? value); 7 | } 8 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | categories: 3 | - title: 🏕 Features 4 | labels: 5 | - features 6 | - user story 7 | - title: 👒 Bugs 8 | labels: 9 | - bug 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/RequestMethod.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveAPI 2 | { 3 | public enum RequestMethod 4 | { 5 | Delete, 6 | Get, 7 | Post, 8 | Put 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/Enums/WHAccessEnums.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.Db.Enums 2 | { 3 | public enum WHAccessEntity 4 | { 5 | Character, 6 | Corporation, 7 | Alliance 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/Enums/SystemLinkEOLStatus.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.Db.Enums 2 | { 3 | public enum SystemLinkEolStatus 4 | { 5 | Normal = 0, 6 | EOL4h = 1, 7 | EOL1h = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/BrowserClientIdProvider/IBrowserClientIdProvider.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.BrowserClientIdProvider; 2 | 3 | public interface IBrowserClientIdProvider 4 | { 5 | Task GetClientIdAsync(); 6 | } 7 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/EveAPIServiceConstants.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveAPI 2 | { 3 | public static class EveAPIServiceConstants 4 | { 5 | public const string ESIUrl = "https://esi.evetech.net"; 6 | } 7 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/SDE/ISDEDataSupplier.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.SDE 2 | { 3 | public interface ISDEDataSupplier 4 | { 5 | public string GetChecksum(); 6 | Task GetSDEDataStreamAsync(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Route/Enums/RouteType.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.EveAPI.Route.Enums 2 | { 3 | public enum RouteType : int 4 | { 5 | Shortest = 0, 6 | Secure = 1, 7 | Insecure =-1 8 | } 9 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/Enums/WHSystemStatusEnums.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.Db.Enums 2 | { 3 | public enum WHSystemStatus 4 | { 5 | Unknown, 6 | Friendly, 7 | Occupied, 8 | Hostile 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHAdmins/IWHAdminRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHAdmins 4 | { 5 | public interface IWHAdminRepository : IDefaultRepository 6 | { 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHAccesses/IWHAccessRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHAccesses 4 | { 5 | public interface IWHAccessRepository : IDefaultRepository 6 | { 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/Validators/IEveOnlineAccessTokenValidator.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveOAuthProvider.Validators; 2 | 3 | public interface IEveOnlineAccessTokenValidator 4 | { 5 | Task ValidateAsync(string accessToken); 6 | } 7 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/Enums/WHAnalizedSignatureEnums.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.EveMapper.Enums 2 | { 3 | 4 | public enum WHAnalizedSignatureEnums 5 | { 6 | toAdd, 7 | toUpdate, 8 | toDelete 9 | } 10 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveScoutAPI/EveScoutAPIServiceConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WHMapper.Services.EveScoutAPI; 4 | 5 | public static class EveScoutAPIServiceConstants 6 | { 7 | public const string EveScoutUrl = "https://api.eve-scout.com"; 8 | } 9 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHJumpLogs/IWHJumpLogRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHJumpLogs 4 | { 5 | public interface IWHJumpLogRepository : IDefaultRepository 6 | { 7 | 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHSystemLinks/IWHSystemLinkRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHSystemLinks 4 | { 5 | public interface IWHSystemLinkRepository : IDefaultRepository 6 | { 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/SDE/SDEStargate.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.SDE; 2 | 3 | public class SDEStargate 4 | { 5 | public int Destination { get; set; } 6 | //public IEnumerable Position { get; set; } 7 | public int TypeID { get; set; } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/WHMapper/RedirectToLogin.razor: -------------------------------------------------------------------------------- 1 | @inject NavigationManager Navigation 2 | 3 | @code { 4 | protected override void OnInitialized() 5 | { 6 | Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}", forceLoad: true); 7 | } 8 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/Anoik/IAnoikDataSupplier.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace WHMapper.Services.Anoik 4 | { 5 | public interface IAnoikDataSupplier 6 | { 7 | JsonElement GetEffects(); 8 | JsonElement GetSystems(); 9 | JsonElement GetWormHoles(); 10 | } 11 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/Cache/ICacheService.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.Cache; 2 | 3 | public interface ICacheService 4 | { 5 | Task Get(string key); 6 | Task Set(string key, T value, TimeSpan? absoluteExpirationRelativeToNow = null); 7 | Task Remove(string key); 8 | } 9 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHNotes/IWHNoteRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHNotes 4 | { 5 | public interface IWHNoteRepository : IDefaultRepository 6 | { 7 | Task Get(int mapId, int solardSystemId); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHSystems/IWHSystemRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHSystems 4 | { 5 | public interface IWHSystemRepository : IDefaultRepository 6 | { 7 | public Task GetByName(string name); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/SDE/SDEConstants.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.SDE 2 | { 3 | public static class SDEConstants 4 | { 5 | public const string REDIS_SOLAR_SYSTEM_JUMPS_KEY = "solarysystemjumps:list"; 6 | public const string REDIS_SDE_SOLAR_SYSTEMS_KEY = "solarsystems:list"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; 2 | using Xunit.Priority; 3 | [assembly: CollectionBehavior(DisableTestParallelization = true)] 4 | [assembly: TestCollectionOrderer("WHMapper.Tests.DisplayNameOrderer", "WHMapper.Tests")] 5 | [assembly: TestCaseOrderer(PriorityOrderer.Name, PriorityOrderer.Assembly)] 6 | 7 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/Enums/WHSignatureEnums.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.Db.Enums 2 | { 3 | public enum WHSignatureGroup 4 | { 5 | Unknow, 6 | Combat, 7 | Wormhole, 8 | Data, 9 | Relic, 10 | Ore, 11 | Gas, 12 | Ghost 13 | 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Search/SearchCharacterResults.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Search 4 | { 5 | public class SearchCharacterResults 6 | { 7 | [JsonPropertyName("character")] 8 | public int[]? Characters { get; set; } 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/Services/IEveUserInfosServices.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveOAuthProvider.Services; 2 | 3 | public interface IEveUserInfosServices 4 | { 5 | public const string ANONYMOUS_USERNAME = "Anonymous"; 6 | Task GetUserName(); 7 | Task GetCharactedID(); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/InlineAutoMoqDataAttribute.cs: -------------------------------------------------------------------------------- 1 | using AutoFixture.Xunit2; 2 | 3 | namespace WHMapper.Tests 4 | { 5 | public class InlineAutoMoqDataAttribute : InlineAutoDataAttribute 6 | { 7 | public InlineAutoMoqDataAttribute(params object[] objects) : base(new AutoMoqDataAttribute(), objects) { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Search/SearchAllianceResults.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Search 4 | { 5 | public class SearchAllianceResults 6 | { 7 | [JsonPropertyName("alliance")] 8 | public int[]? Alliances { get; set; } = null!; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Search/SearchCoporationResults.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Search 4 | { 5 | public class SearchCoporationResults 6 | { 7 | [JsonPropertyName("corporation")] 8 | public int[]? Corporations { get; set; } 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper/Services/Paste/PasteServices.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper; 2 | 3 | public class PasteServices : IPasteServices 4 | { 5 | public event Func Pasted = null!; 6 | 7 | public Task Paste(string? value) 8 | { 9 | Pasted?.Invoke(value); 10 | return Task.CompletedTask; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Corporations/ICorporationServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Corporation; 3 | 4 | namespace WHMapper.Services.EveAPI.Corporations 5 | { 6 | public interface ICorporationServices 7 | { 8 | Task> GetCorporation(int corporation_id); 9 | } 10 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/Services/IClaimServices.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.Security.Claims; 3 | 4 | namespace WHMapper.Services.EveOAuthProvider.Services; 5 | 6 | public interface IClaimServices 7 | { 8 | Task> ExtractClaimsFromEVEToken([NotNull] string token); 9 | } 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/User Interface/IUserInterfaceServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | 3 | namespace WHMapper.Services.EveAPI.UserInterface 4 | { 5 | public interface IUserInterfaceServices 6 | { 7 | Task> SetWaypoint(int destination_id, bool add_to_beginning = false, bool clear_other_waypoints = false); 8 | } 9 | } -------------------------------------------------------------------------------- /deploy/docker/haproxy/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | 5 | server_name mydomain.com; 6 | server_tokens off; 7 | 8 | location /.well-known/acme-challenge/ { 9 | root /var/www/certbot; 10 | } 11 | 12 | location / { 13 | return 301 https://mydomain.com$request_uri; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/DomainCustomization.cs: -------------------------------------------------------------------------------- 1 | using AutoFixture; 2 | using AutoFixture.AutoMoq; 3 | 4 | namespace WHMapper.Tests 5 | { 6 | public class DomainCustomization : CompositeCustomization 7 | { 8 | public DomainCustomization() : base( 9 | new AutoMoqCustomization() 10 | ) 11 | { } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WHMapper.Models.DTO; 4 | 5 | public class UserToken 6 | { public string? AccountId { get; set; } // Unique user identifier 7 | public string? AccessToken { get; set; } 8 | public string? RefreshToken { get; set; } 9 | public DateTime Expiry { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/AuthorizationPolicies/EveMapperMapRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | 4 | namespace WHMapper.Services.EveMapper.AuthorizationPolicies; 5 | 6 | public class EveMapperMapRequirement: IAuthorizationRequirement 7 | { 8 | public EveMapperMapRequirement() 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/WHMapper/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "WHMapper": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Locations/ILocationServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Location; 3 | 4 | namespace WHMapper.Services.EveAPI.Locations 5 | { 6 | public interface ILocationServices 7 | { 8 | Task> GetLocation(); 9 | Task> GetCurrentShip(); 10 | } 11 | } -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Notes/Overview.razor: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHRoutes/IWHRouteRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Repositories; 2 | 3 | namespace WHMapper; 4 | 5 | public interface IWHRouteRepository : IDefaultRepository 6 | { 7 | Task> GetRoutesByEveEntityId(int mapId,int eveEntityId); 8 | Task> GetRoutesForAll(int mapId); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Alliances/IAllianceServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Alliance; 3 | 4 | namespace WHMapper.Services.EveAPI.Alliances 5 | { 6 | public interface IAllianceServices 7 | { 8 | Task> GetAlliances(); 9 | Task> GetAlliance(int alliance_id); 10 | } 11 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/AuthorizationPolicies/EveMapperAdminRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace WHMapper.Services.EveMapper.AuthorizationPolicies 4 | { 5 | public class EveMapperAdminRequirement : IAuthorizationRequirement 6 | { 7 | public EveMapperAdminRequirement() 8 | { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/AutoDomainDataAttribute.cs: -------------------------------------------------------------------------------- 1 | using AutoFixture; 2 | using AutoFixture.Xunit2; 3 | 4 | namespace WHMapper.Tests 5 | { 6 | public class AutoDomainDataAttribute : AutoDataAttribute 7 | { 8 | public AutoDomainDataAttribute() 9 | : base(() => new Fixture().Customize(new DomainCustomization())) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/AuthorizationPolicies/EveMapperAccessRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace WHMapper.Services.EveMapper.AuthorizationPolicies 4 | { 5 | public class EveMapperAccessRequirement : IAuthorizationRequirement 6 | { 7 | public EveMapperAccessRequirement() 8 | { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/ResponseMessage/SuccessMessage.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.ResponseMessage 2 | { 3 | public class SuccessMessage : IResponseMessage 4 | { 5 | public T Response { get; private set; } 6 | 7 | public SuccessMessage(T responseMsg) 8 | { 9 | Response = responseMsg; 10 | } 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/AutoMoqDataAttribute.cs: -------------------------------------------------------------------------------- 1 | using AutoFixture; 2 | using AutoFixture.AutoMoq; 3 | using AutoFixture.Xunit2; 4 | 5 | namespace WHMapper.Tests 6 | { 7 | public class AutoMoqDataAttribute : AutoDataAttribute 8 | { 9 | public AutoMoqDataAttribute() 10 | : base(() => new Fixture().Customize(new AutoMoqCustomization())) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/SDE/SDESecondarySun.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.SDE 2 | { 3 | public class SDESecondarySun 4 | { 5 | public int EffectBeaconTypeID { get; set; } 6 | public int ItemID { get; set; } 7 | //public IEnumerable Position { get; set; } 8 | public int TypeID { get; set; } 9 | 10 | 11 | public SDESecondarySun() {} 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/Enums/WHSystemLinkEnums.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.Db.Enums 2 | { 3 | public enum SystemLinkSize : int 4 | { 5 | Small = 0, 6 | Medium = 1, 7 | Large = 2, 8 | XLarge = 3 9 | } 10 | 11 | public enum SystemLinkMassStatus : int 12 | { 13 | Normal = 0, 14 | Critical = 1, 15 | Verge = 2 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Characters/ICharacterServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Character; 3 | 4 | namespace WHMapper.Services.EveAPI.Characters 5 | { 6 | public interface ICharacterServices 7 | { 8 | Task> GetCharacter(int character_id); 9 | Task> GetCharacterPortrait(int character_id); 10 | } 11 | } -------------------------------------------------------------------------------- /src/WHMapper/Repositories/IDefaultRepository.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Repositories 2 | { 3 | public interface IDefaultRepository 4 | { 5 | Task?> GetAll(); 6 | Task GetById(U id); 7 | Task Create(T item); 8 | Task Update(U id, T item); 9 | Task DeleteById(U id); 10 | Task GetCountAsync(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Assets/IAssetsServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Assets; 3 | 4 | namespace WHMapper.Services.EveAPI.Assets 5 | { 6 | public interface IAssetsServices 7 | { 8 | Task>> GetMyAssets(int page = 1); 9 | Task>> GetCharacterAssets(int character_id, int page = 1); 10 | } 11 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/EVEOnlinePostConfigureOptions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Options; 2 | 3 | namespace WHMapper.Services.EveOAuthProvider 4 | { 5 | public class EVEOnlinePostConfigureOptions : IPostConfigureOptions 6 | { 7 | public void PostConfigure(string? name, EVEOnlineAuthenticationOptions options) 8 | { 9 | 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/ResponseMessage/ErrorMessage.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.ResponseMessage 4 | { 5 | public class ErrorMessage : IResponseMessage 6 | { 7 | [JsonPropertyName("code")] 8 | public int? Code { get; set; } 9 | 10 | [JsonPropertyName("message")] 11 | public string? Message { get; set; } 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperAccessHelper.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveMapper 2 | { 3 | public interface IEveMapperAccessHelper 4 | { 5 | public Task IsEveMapperUserAccessAuthorized(int eveCharacterId); 6 | public Task IsEveMapperAdminAccessAuthorized(int eveCharacterId); 7 | public Task IsEveMapperMapAccessAuthorized(int eveCharacterId, int mapId); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/SDE/ISDEServiceManager.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.SDE 2 | { 3 | public interface ISDEServiceManager 4 | { 5 | bool IsExtractionSuccesful(); 6 | Task IsNewSDEAvailable(); 7 | Task DownloadSDE(); 8 | Task ExtractSDE(); 9 | Task BuildCache(); 10 | Task ClearCache(); 11 | Task ClearSDEResources(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Routes.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/WHMapper/Services/SDE/ISDEService.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.SDE; 2 | 3 | namespace WHMapper.Services.SDE 4 | { 5 | public interface ISDEService 6 | { 7 | Task?> GetSolarSystemList(); 8 | Task?> GetSolarSystemJumpList(); 9 | Task?> SearchSystem(string value); 10 | Task SearchSystemById(int value); 11 | } 12 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveSystemEffect.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.EveMapper 2 | { 3 | public class EveSystemEffect 4 | { 5 | public string Name { get; private set; } 6 | /// 7 | /// Value is in % 8 | /// 9 | public int Value { get; private set; } 10 | 11 | public EveSystemEffect(string name,int value) 12 | { 13 | Name = name; 14 | Value = value; 15 | } 16 | } 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/SDE/SolarSystem.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.SDE; 2 | 3 | public class SolarSystem 4 | { 5 | public int SolarSystemId { get; set; } 6 | public float Security { get; set; } 7 | 8 | public SolarSystem() 9 | { 10 | 11 | } 12 | 13 | public SolarSystem(int solarSystemId,float security) 14 | { 15 | SolarSystemId = solarSystemId; 16 | Security = security; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Assets/AssetName.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper; 4 | 5 | public class AssetName 6 | { 7 | [JsonPropertyName("item_id")] 8 | public long ItemId { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string Name { get; set; } 12 | 13 | [JsonConstructor] 14 | public AssetName(long item_id, string name) => 15 | (ItemId, Name) = (item_id, name); 16 | } 17 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Dogma/IDogmaServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Dogma; 3 | 4 | namespace WHMapper.Services.EveAPI.Dogma 5 | { 6 | public interface IDogmaServices 7 | { 8 | Task> GetAttributes(); 9 | Task> GetAttribute(int attribute_id); 10 | Task> GetEffects(); 11 | Task> GetEffect(int effect_id); 12 | } 13 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Location/Ship.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Location 4 | { 5 | public class Ship 6 | { 7 | [JsonPropertyName("ship_item_id")] 8 | public long ShipItemId { get; set; } 9 | 10 | [JsonPropertyName("ship_name")] 11 | public string? ShipName { get; set; } 12 | [JsonPropertyName("ship_type_id")] 13 | public int ShipTypeId { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/RoutePlanner/Delete.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @if (RouteId > 0) 4 | { 5 | @MSG_DELETE_ROUTE 6 | } 7 | 8 | 9 | Cancel 10 | Delete 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/DisplayNameOrderer.cs: -------------------------------------------------------------------------------- 1 | using Xunit.Abstractions; 2 | 3 | namespace WHMapper.Tests; 4 | 5 | public class DisplayNameOrderer : ITestCollectionOrderer 6 | { 7 | public IEnumerable OrderTestCollections(IEnumerable testCollections) 8 | { 9 | var orderedCollections = testCollections.OrderBy(collection => collection.DisplayName); 10 | return orderedCollections; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/WHMapper/wwwroot/WHMapper.lib.module.js: -------------------------------------------------------------------------------- 1 | export function afterServerStarted(blazor) { 2 | setup(blazor); 3 | } 4 | 5 | export function afterWebAssemblyStarted(blazor) { 6 | setup(blazor); 7 | } 8 | 9 | function setup(blazor) { 10 | blazor.registerCustomEventType('custompaste', { 11 | browserEventName: 'paste', 12 | createEventArgs: event => ({ 13 | eventTimestamp: new Date().toISOString(), 14 | pastedData: event.clipboardData.getData('text'), 15 | }) 16 | }); 17 | } -------------------------------------------------------------------------------- /src/WHMapper/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using WHMapper 10 | @using WHMapper.Components 11 | @using Microsoft.AspNetCore.Components.Authorization 12 | @using MudBlazor 13 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/Enums/EveEntityEnums.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.EveMapper.Enums 2 | {public enum EveEntityEnums 3 | { 4 | Character, 5 | Corporation, 6 | Alliance, 7 | Ship, 8 | System, 9 | Constellation, 10 | Region, 11 | Stargate, 12 | Station, 13 | Structure, 14 | Group, 15 | Wormhole, 16 | Sun, 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Location/Activity.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.EveAPI.Location 2 | { 3 | public class Activity 4 | { 5 | /* 6 | [JsonProperty("online")] 7 | public bool Online { get; set; } 8 | 9 | [JsonProperty("last_login")] 10 | public DateTime LastLogin { get; set; } 11 | 12 | [JsonProperty("last_logout")] 13 | public DateTime LastLogout { get; set; } 14 | 15 | [JsonProperty("logins")] 16 | public int Logins { get; set; }*/ 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/Services/IEveOnlineTokenProvider.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | 3 | namespace WHMapper.Services.EveOAuthProvider.Services; 4 | 5 | public interface IEveOnlineTokenProvider 6 | { 7 | Task SaveToken(UserToken token); 8 | Task GetToken(string accountId,bool autoResfred = false); 9 | Task ClearToken(string accountId); 10 | Task IsTokenExpire(string accountId); 11 | Task RefreshAccessToken(string accountId); 12 | Task RevokeToken(string accountId); 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /.clabot: -------------------------------------------------------------------------------- 1 | { 2 | "message": "We require contributors to sign our Contributor License Agreement (CLA), and we don't have yours on file. In order for us to review and merge your code, please sign [CLA]('https://github.com/pfh59/eve-whmapper/blob/main/CLA.md') to get yourself added.\n\nTeammates should refer to [Accepting contributions](https://github.com/pfh59/eve-whmapper/blob/main/CONTRIBUTING.md) for guidance.", 3 | "label": "cla-signed", 4 | "contributors": [ 5 | "pfh59", 6 | "rdymade", 7 | "Blackout76", 8 | "pkoelemij" 9 | ] 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Search/ISearchServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Search; 3 | 4 | namespace WHMapper.Services.EveAPI.Search 5 | { 6 | public interface ISearchServices 7 | { 8 | Task> SearchAlliance(string searchValue, bool isStrict = false); 9 | Task> SearchCorporation(string searchValue, bool isStrict = false); 10 | Task> SearchCharacter(string searchValue, bool isStrict = false); 11 | } 12 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperTracker.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveAPI.Location; 2 | 3 | namespace WHMapper.Services.EveMapper; 4 | 5 | public interface IEveMapperTracker : IAsyncDisposable 6 | { 7 | event Func? SystemChanged; 8 | event Func? ShipChanged; 9 | event Func? TrackingLocationRetryRequested; 10 | event Func? TrackingShipRetryRequested; 11 | Task StartTracking(int accountID); 12 | Task StopTracking(int accountID); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/WHMapperUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WHMapper.Models.DTO.EveMapper; 4 | 5 | public class WHMapperUser 6 | { 7 | public int Id { get; private set; } 8 | public string PortraitUrl { get; private set; } 9 | public bool Tracking { get; set; } 10 | public bool IsPrimary { get; set; } 11 | 12 | public WHMapperUser(int id, string portraitUrl, bool tracking = true) 13 | { 14 | Id = id; 15 | PortraitUrl = portraitUrl; 16 | Tracking = tracking; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHMaps/IWHMapRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHMaps 4 | { 5 | public interface IWHMapRepository : IDefaultRepository 6 | { 7 | Task GetByNameAsync(string mapName); 8 | Task DeleteAll(); 9 | Task?> GetMapAccesses(int id); 10 | Task DeleteMapAccess(int mapId, int accessId); 11 | Task DeleteMapAccesses(int mapId); 12 | Task AddMapAccess(int mapId, int accessId); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Administration/Map/Add.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Cancel 9 | Add Map 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/SunEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveMapper.Enums; 3 | 4 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 5 | 6 | public class SunEntity : AEveEntity 7 | { 8 | public SunEntity(int id, WHMapper.Models.DTO.EveAPI.Universe.Type type) 9 | : base(id, type.Name, EveEntityEnums.Sun) 10 | { 11 | } 12 | 13 | [JsonConstructor] 14 | public SunEntity(int id, string name) 15 | : base(id, name, EveEntityEnums.Sun) 16 | { 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Position.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI 4 | { 5 | public class Position 6 | { 7 | [JsonPropertyName("x")] 8 | public required double X { get; set; } 9 | 10 | [JsonPropertyName("y")] 11 | public required double Y { get; set; } 12 | 13 | [JsonPropertyName("z")] 14 | public required double Z { get; set; } 15 | 16 | [JsonConstructor] 17 | public Position(double x, double y, double z) => (X, Y, Z) = (x, y, z); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/Enums/WHEffectEnums.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace WHMapper.Models.DTO.EveMapper.Enums 4 | { 5 | public enum WHEffect 6 | { 7 | [Description("Magnetar")] 8 | Magnetar, 9 | [Description("Red Giant")] 10 | RedGiant, 11 | [Description("Pulsar")] 12 | Pulsar, 13 | [Description("Wolf-Rayet Star")] 14 | WolfRayet, 15 | [Description("Cataclysmic Variable")] 16 | Cataclysmic, 17 | [Description("Black Hole")] 18 | BlackHole, 19 | None 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Character/Portrait.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.Json.Serialization; 3 | 4 | namespace WHMapper.Models.DTO.EveAPI.Character; 5 | 6 | public class Portrait 7 | { 8 | 9 | [JsonPropertyName("px128x128")] 10 | public string Picture128x128 { get; set; } 11 | 12 | [JsonPropertyName("px256x256")] 13 | public string Picture256x256 { get; set; } 14 | 15 | [JsonPropertyName("px512x512")] 16 | public string Picture512x512 { get; set; } 17 | 18 | [JsonPropertyName("px64x64")] 19 | public string Picture64x64 { get; set; } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Region.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class Region 6 | { 7 | [JsonPropertyName("region_id")] 8 | public required int RegionId { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public required string Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("constellations")] 17 | public required int[] Constellations { get; set; } 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/WHMapper/Repositories/WHSignatures/IWHSignatureRepository.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Repositories.WHSignatures 4 | { 5 | 6 | public interface IWHSignatureRepository : IDefaultRepository 7 | { 8 | Task GetByName(string name); 9 | Task?> Update(IEnumerable whSignatures); 10 | Task?> GetByWHId(int whid); 11 | Task DeleteByWHId(int whid); 12 | Task?> Create(IEnumerable whSignatures); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Signatures/Delete.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @if (SignatureId > 0) 4 | { 5 | @MSG_DELETE_SIGNATURE 6 | } 7 | else 8 | { 9 | @MSG_DELETE_SIGNATURES 10 | } 11 | 12 | 13 | Cancel 14 | Delete 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Administration/Map/Delete.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @if (MapId > 0) 4 | { 5 | @MSG_DELETE_MAP 6 | } 7 | else 8 | { 9 | @MSG_DELETE_MAPS 10 | } 11 | 12 | 13 | Cancel 14 | Delete 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/AEveEntity.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper.Enums; 2 | 3 | namespace WHMapper.Models.DTO.EveMapper.EveEntity 4 | { 5 | public abstract class AEveEntity 6 | { 7 | public int Id { get; private set; } 8 | public string Name { get; private set; } 9 | 10 | public EveEntityEnums EntityType { get; private set; } 11 | 12 | public AEveEntity(int id, string name, EveEntityEnums entityType) 13 | { 14 | Id = id; 15 | Name = name; 16 | EntityType = entityType; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/Services/Cache/FakeCacheObject.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Tests.Services.Cache 2 | { 3 | public class FakeCacheObject 4 | { 5 | public int Id { get; set; } 6 | public string? Name { get; set; } 7 | 8 | public override bool Equals(object? obj) 9 | { 10 | if (obj is FakeCacheObject other) 11 | { 12 | return Id == other.Id && Name == other.Name; 13 | } 14 | return false; 15 | } 16 | 17 | public override int GetHashCode() 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Administration/Access/Delete.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @if (AccessId > 0) 4 | { 5 | @MSG_ACCESS_DELETE 6 | } 7 | 8 | @if (AdminId > 0) 9 | { 10 | @MSG_ADMIN_DELETE 11 | } 12 | 13 | 14 | Cancel 15 | Delete 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/MapAdmin/MapAdmin.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db; 2 | 3 | namespace WHMapper.Models.DTO.MapAdmin; 4 | 5 | public class MapAdmin 6 | { 7 | private WHMap? map = null; 8 | public int Id => map?.Id ?? -1; 9 | public string Name => map?.Name ?? string.Empty; 10 | public IEnumerable? WHMapAccesses => map?.WHAccesses; 11 | public bool ShowAccessDetails { get; set; } = false; 12 | 13 | public MapAdmin(WHMapper.Models.Db.WHMap map) 14 | { 15 | this.map = map; 16 | this.ShowAccessDetails = false; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHAdmin.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace WHMapper.Models.Db 4 | { 5 | public class WHAdmin 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | [Required] 11 | public int EveCharacterId { get; set; } 12 | 13 | [Required] 14 | public string EveCharacterName { get; set; }=string.Empty; 15 | 16 | public WHAdmin() { } 17 | public WHAdmin(int eveCharacterId,string eveCharacterName) 18 | { 19 | EveCharacterId = eveCharacterId; 20 | EveCharacterName = eveCharacterName; 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /deploy/kubernetes/deploys/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: evemapper-ingress 5 | namespace: evemapper 6 | annotations: 7 | kubernetes.io/ingress.class: traefik 8 | labels: 9 | order: "12" 10 | spec: 11 | ingressClassName: traefik 12 | tls: 13 | - hosts: 14 | - [your SUB/DOMAIN] 15 | secretName: tls-evemapper 16 | rules: 17 | - host: [your SUB/DOMAIN] 18 | http: 19 | paths: 20 | - path: / 21 | pathType: Prefix 22 | backend: 23 | service: 24 | name: evemapper-app-service 25 | port: 26 | number: 8080 -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Administration/Map/RemoveAccess.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @if (MapId > 0) 4 | { 5 | @MSG_DELETE_ACCESS 6 | } 7 | else 8 | { 9 | @MSG_DELETE_ACCESSES 10 | } 11 | 12 | 13 | Cancel 14 | Delete Access 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveJwTExtensions/EveOnlineJwkDefaults.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveJwkExtensions 2 | { 3 | public class EveOnlineJwkDefaults 4 | { 5 | public const string AuthenticationScheme = "EveOnlineBearer"; 6 | public static readonly string EVE_HOST = "login.eveonline.com"; 7 | public static readonly string SSOUrl = "https://login.eveonline.com"; 8 | public static readonly string JWKEndpoint = "https://login.eveonline.com/oauth/jwks"; 9 | public static readonly string ValideIssuer = "https://login.eveonline.com"; 10 | public static readonly string ValideAudience = "EVE Online"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/WHMapper/Services/Anoik/IAnoikServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.Anoik; 2 | 3 | namespace WHMapper.Services.Anoik 4 | { 5 | public interface IAnoikServices 6 | { 7 | public int? GetSystemId(string systemName); 8 | public string? GetSystemClass(string systemName); 9 | public string? GetSystemEffects(string systemName); 10 | public Task>> GetSystemStatics(string systemName); 11 | public IEnumerable> GetSystemEffectsInfos(string effectName, string systemClass); 12 | public Task> GetWormholeTypes(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Routes/IRouteServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Route.Enums; 3 | 4 | namespace WHMapper.Services.EveAPI.Routes 5 | { 6 | public interface IRouteServices 7 | { 8 | Task> GetRoute(int from, int to); 9 | Task> GetRoute(int from, int to, int[]? avoid); 10 | Task> GetRoute(int from, int to, int[][]? connections); 11 | Task> GetRoute(int from, int to, int[]? avoid, int[][]? connections); 12 | Task> GetRoute(int from, int to, RouteType routeType, int[]? avoid, int[][]? connections); 13 | } 14 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/AllianceEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Alliance; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity 6 | { 7 | 8 | public class AllianceEntity : AEveEntity 9 | { 10 | public AllianceEntity(int id, Alliance entity) 11 | : base(id, entity.Name, EveEntityEnums.Alliance) 12 | { 13 | } 14 | 15 | [JsonConstructor] 16 | public AllianceEntity(int id, string name) 17 | : base(id, name, EveEntityEnums.Alliance) 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/CharactereEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Character; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity 6 | { 7 | public class CharactereEntity : AEveEntity 8 | { 9 | public CharactereEntity(int id, Character entity) 10 | : base(id, entity.Name, EveEntityEnums.Character) 11 | { 12 | } 13 | 14 | [JsonConstructor] 15 | public CharactereEntity(int id, string name) 16 | : base(id, name, EveEntityEnums.Character) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperUserManagementService.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveMapper; 3 | 4 | namespace WHMapper.Services.EveMapper; 5 | 6 | public interface IEveMapperUserManagementService 7 | { 8 | Task AddAuthenticateWHMapperUser(string clientId,string accountId,UserToken token); 9 | Task RemoveAuthenticateWHMapperUser(string clientId,string accountId); 10 | Task RemoveAuthenticateWHMapperUser(string clientId); 11 | Task GetAccountsAsync(string clientId); 12 | Task GetPrimaryAccountAsync(string clientId); 13 | Task SetPrimaryAccountAsync(string clientId,string accountId); 14 | } 15 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/CorporationEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Corporation; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity 6 | { 7 | public class CorporationEntity : AEveEntity 8 | { 9 | public CorporationEntity(int id, Corporation entity) 10 | : base(id, entity.Name, EveEntityEnums.Corporation) 11 | { 12 | } 13 | 14 | [JsonConstructor] 15 | public CorporationEntity(int id, string name) 16 | : base(id, name, EveEntityEnums.Corporation) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveScoutAPI/IEveScoutAPIServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WHMapper.Models.DTO.EveScout; 3 | 4 | namespace WHMapper.Services.EveScoutAPI; 5 | 6 | public interface IEveScoutAPIServices 7 | { 8 | 9 | /// 10 | /// Fetches all Thera system entries. 11 | /// 12 | /// A list of Thera system entries. 13 | Task?> GetTheraSystemsAsync(); 14 | 15 | /// 16 | /// Fetches all Turnur system entries. 17 | /// 18 | /// A list of Turnur system entries. 19 | Task?> GetTurnurSystemsAsync(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/SDE/SolarSystemJump.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.SDE; 2 | 3 | 4 | public class SolarSystemJump 5 | { 6 | public SolarSystem System { get; set; } = null!; 7 | public IEnumerable JumpList { get; set; } = null!; 8 | 9 | public SolarSystemJump() 10 | { 11 | 12 | } 13 | public SolarSystemJump(int solarSystemId,float security) : this(solarSystemId, security,new List()) 14 | { 15 | 16 | } 17 | 18 | public SolarSystemJump(int solarSystemId,float security, IEnumerable jumpList) 19 | { 20 | System=new SolarSystem(solarSystemId,security); 21 | JumpList = jumpList; 22 | } 23 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Corporations/CorporationServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Corporation; 3 | 4 | namespace WHMapper.Services.EveAPI.Corporations 5 | { 6 | public class CorporationServices : EveApiServiceBase, ICorporationServices 7 | { 8 | public CorporationServices(HttpClient httpClient) 9 | : base(httpClient) 10 | { 11 | } 12 | 13 | public async Task> GetCorporation(int corporation_id) 14 | { 15 | return await Execute(RequestSecurity.Public, RequestMethod.Get, string.Format("/v5/corporations/{0}/?datasource=tranquility", corporation_id)); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Constellation.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class Constellation 6 | { 7 | [JsonPropertyName("constellation_id")] 8 | public required int ConstellationId { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public required string Name { get; set; } 12 | 13 | [JsonPropertyName("position")] 14 | public required Position Position { get; set; } 15 | 16 | [JsonPropertyName("region_id")] 17 | public required int RegionId { get; set; } 18 | 19 | [JsonPropertyName("systems")] 20 | public required int[] Systems { get; set; } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/RoutePlanner/RouteConnection.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.RoutePlanner; 2 | 3 | public class RouteConnection 4 | { 5 | public int FromSolarSystemId { get; set; } 6 | public float FromSecurity { get; set; } 7 | 8 | public int ToSolarSystemId { get; set; } 9 | public float ToSecurity { get; set; } 10 | 11 | public RouteConnection() 12 | { 13 | 14 | } 15 | 16 | public RouteConnection(int fromSolarSystemId,float fromSecurity,int toSolarSystemId,float toSecurity) 17 | { 18 | FromSolarSystemId = fromSolarSystemId; 19 | FromSecurity = fromSecurity; 20 | ToSolarSystemId = toSolarSystemId; 21 | ToSecurity = toSecurity; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/ShipEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveMapper.Enums; 3 | 4 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 5 | 6 | public class ShipEntity: AEveEntity 7 | { 8 | public float Mass {get;private set;} 9 | public ShipEntity(int id, Models.DTO.EveAPI.Universe.Type entity) 10 | : base(id, entity.Name, EveEntityEnums.Ship) 11 | { 12 | Mass = entity.Mass; 13 | } 14 | 15 | [JsonConstructor] 16 | public ShipEntity(int id, string name,float mass) 17 | : base(id, name, EveEntityEnums.Ship) 18 | { 19 | Mass = mass; 20 | } 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Location/EveLocation.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | 4 | namespace WHMapper.Models.DTO.EveAPI.Location 5 | { 6 | public class EveLocation 7 | { 8 | [JsonPropertyName("solar_system_id")] 9 | public int SolarSystemId { get; private set; } 10 | 11 | [JsonPropertyName("station_id")] 12 | public int StationId { get; private set; } 13 | 14 | [JsonPropertyName("structure_id")] 15 | public long StructureId { get; private set; } 16 | 17 | [JsonConstructor] 18 | public EveLocation(int solarSystemId, int stationId, long structureId) => 19 | (SolarSystemId, StationId, StructureId) = (solarSystemId, stationId, structureId); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WHMapper/Services/WHColor/IWHColorHelper.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db.Enums; 2 | using WHMapper.Models.DTO.EveMapper.Enums; 3 | 4 | namespace WHMapper.Services.WHColor 5 | { 6 | public interface IWHColorHelper 7 | { 8 | const string DEFAULT_COLOR = "grey"; 9 | 10 | string GetSecurityStatusColor(float secStatus); 11 | string GetSystemTypeColor(EveSystemType systemType); 12 | string GetEffectColor(WHEffect effect); 13 | string GetLinkEOLColor(SystemLinkEolStatus status); 14 | string GetLinkStatusColor(SystemLinkMassStatus status); 15 | string GetLinkSelectedColor(); 16 | string GetNodeStatusColor(WHSystemStatus status); 17 | string GetWHAnalyzedSignatureColor(WHAnalizedSignatureEnums status); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/RegionEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Universe; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 6 | 7 | public class RegionEntity : AEveEntity 8 | { 9 | public int[] Constellations { get; private set; } 10 | 11 | public RegionEntity(int id, Region region) 12 | : base(id, region.Name, EveEntityEnums.Region) 13 | { 14 | Constellations = region.Constellations; 15 | 16 | } 17 | 18 | [JsonConstructor] 19 | public RegionEntity(int id, string name, int[] constellations) 20 | : base(id, name, EveEntityEnums.Region) 21 | { 22 | Constellations = constellations; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class Category 6 | { 7 | [JsonPropertyName("category_id")] 8 | public int CategoryId { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string Name { get; set; } 12 | 13 | [JsonPropertyName("published")] 14 | public bool Published { get; set; } 15 | 16 | [JsonPropertyName("groups")] 17 | public int[] Groups { get; set; } 18 | 19 | 20 | [JsonConstructor] 21 | public Category(int categoryId, int[] groups,string name, bool published) => 22 | (CategoryId, Groups,Name, Published) = (categoryId, groups,name, published); 23 | 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperService.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper.EveEntity; 2 | 3 | namespace WHMapper.Services.EveMapper; 4 | 5 | public interface IEveMapperService 6 | { 7 | Task GetCharacter(int characterId); 8 | Task GetCorporation(int corporationId); 9 | Task GetAlliance(int allianceId); 10 | Task GetShip(int shipTypeId); 11 | Task GetSystem(int systemId); 12 | Task GetConstellation(int constellationId); 13 | Task GetRegion(int regionId); 14 | Task GetStargate(int stargateId); 15 | Task GetGroup(int groupId); 16 | Task GetWormhole(int wormholeTypeId); 17 | Task GetSun(int sunTypeId); 18 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/WHAnalizedSignature.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper.Enums; 2 | 3 | namespace WHMapper.Models.DTO.EveMapper 4 | { 5 | 6 | 7 | public class WHAnalizedSignature 8 | { 9 | private readonly WHMapper.Models.Db.WHSignature _signature; 10 | public WHAnalizedSignatureEnums Status { get; private set;} 11 | 12 | public string Name { get { return _signature.Name; } } 13 | public string Group { get { return _signature.Group.ToString(); } } 14 | public string? Type { get { return _signature.Type; } } 15 | 16 | public WHAnalizedSignature(WHMapper.Models.Db.WHSignature whsig,WHAnalizedSignatureEnums status) 17 | { 18 | _signature= whsig; 19 | Status = status; 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/WHMapper/EventHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | 3 | namespace WHMapper 4 | { 5 | [EventHandler("oncustompaste", typeof(CustomPasteEventArgs),enableStopPropagation: true, enablePreventDefault: true)] 6 | public static class EventHandlers 7 | { 8 | // This static class doesn't need to contain any members. It's just a place where we can put 9 | // [EventHandler] attributes to configure event types on the Razor compiler. This affects the 10 | // compiler output as well as code completions in the editor. 11 | } 12 | 13 | public class CustomPasteEventArgs : EventArgs 14 | { 15 | // Data for these properties will be supplied by custom JavaScript logic 16 | public DateTime EventTimestamp { get; set; } 17 | public string? PastedData { get; set; } 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/SSO/EveToken.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.SSO 4 | { 5 | 6 | public class EveToken 7 | { 8 | [JsonPropertyName("access_token")] 9 | public string AccessToken { get; private set; } 10 | [JsonPropertyName("token_type")] 11 | public string TokenType { get; private set; } 12 | [JsonPropertyName("expires_in")] 13 | public int ExpiresIn { get; private set; } 14 | [JsonPropertyName("refresh_token")] 15 | public string RefreshToken { get; private set; } 16 | 17 | 18 | [JsonConstructor] 19 | public EveToken(string accessToken, string tokenType, int expiresIn, string refreshToken) => (AccessToken, TokenType, ExpiresIn, RefreshToken) = (accessToken, tokenType, expiresIn, refreshToken); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHMap.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace WHMapper.Models.Db 4 | { 5 | public class WHMap 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | [Required] 11 | [StringLength(255, ErrorMessage = "Map name is too long.")] 12 | public string Name { get; set; } = string.Empty; 13 | public virtual ICollection WHSystems { get; } = new HashSet(); 14 | public virtual ICollection WHSystemLinks { get; } = new HashSet(); 15 | public virtual ICollection WHAccesses { get; } = new HashSet(); 16 | 17 | [Obsolete("EF Requires it")] 18 | protected WHMap() { } 19 | 20 | public WHMap(string name) 21 | { 22 | Name = name; 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using WHMapper.Models.Custom.Node; 3 | using WHMapper.Models.Db; 4 | using WHMapper.Models.DTO.EveMapper; 5 | using WHMapper.Models.DTO.EveMapper.Enums; 6 | using WHMapper.Models.DTO.EveMapper.EveEntity; 7 | 8 | namespace WHMapper.Services.EveMapper 9 | { 10 | public interface IEveMapperHelper 11 | { 12 | ReadOnlyCollection WormholeTypes { get; } 13 | Task DefineEveSystemNodeModel(WHSystem wh); 14 | bool IsWormhole(string systemName); 15 | Task GetWHClass(SystemEntity whSystem); 16 | Task GetWHClass(string regionName, string constellationName, string systemName, float securityStatus); 17 | Task IsRouteViaWH(SystemEntity src, SystemEntity dst); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/GroupEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Universe; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 6 | 7 | public class GroupEntity : AEveEntity 8 | { 9 | public int[] Types { get; private set; } 10 | public int CategoryId { get; private set; } 11 | public GroupEntity(int id, Group group) 12 | : base(id, group.Name, EveEntityEnums.Group) 13 | { 14 | Types = group.Types; 15 | CategoryId = group.CategoryId; 16 | } 17 | 18 | [JsonConstructor] 19 | public GroupEntity(int id, string name,int[] types,int categoryId) 20 | : base(id, name, EveEntityEnums.Group) 21 | { 22 | Types = types; 23 | CategoryId = categoryId; 24 | 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/User Interface/UserInterfaceServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | 3 | namespace WHMapper.Services.EveAPI.UserInterface 4 | { 5 | public class UserInterfaceServices : EveApiServiceBase, IUserInterfaceServices 6 | { 7 | public UserInterfaceServices(HttpClient httpClient, UserToken? userToken = null) 8 | : base(httpClient, userToken) 9 | { 10 | } 11 | 12 | public async Task> SetWaypoint(int destination_id, bool add_to_beginning = false, bool clear_other_waypoints = false) 13 | { 14 | return await base.Execute(RequestSecurity.Authenticated, RequestMethod.Post, string.Format("v2/ui/autopilot/waypoint?datasource=tranquility&destination_id={0}&add_to_beginning={1}&clear_other_waypoints={2}", destination_id, add_to_beginning, clear_other_waypoints)); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Alliances/AllianceServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | 3 | namespace WHMapper.Services.EveAPI.Alliances 4 | { 5 | public class AllianceServices : EveApiServiceBase, IAllianceServices 6 | { 7 | public AllianceServices(HttpClient httpClient) : base(httpClient) 8 | { 9 | } 10 | 11 | public async Task> GetAlliance(int alliance_id) 12 | { 13 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, string.Format("/v4/alliances/{0}/?datasource=tranquility", alliance_id)); 14 | } 15 | 16 | public async Task> GetAlliances() 17 | { 18 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, "/v2/alliances/?datasource=tranquility"); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/Anoik/WormholeTypeInfo.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Models.DTO.Anoik 2 | { 3 | public class WormholeTypeInfo 4 | { 5 | public string Name { private set; get; } 6 | public string? Destination { private set; get; } 7 | public string[]? Sources { private set; get; } 8 | 9 | public WormholeTypeInfo(string name, string? dest, string[]? srcs) 10 | { 11 | Name = name; 12 | Destination = (!string.IsNullOrEmpty(dest) ? dest.ToUpper() : null); 13 | Sources = (srcs != null ? srcs.Select(x => x.ToUpper()).ToArray() : null); 14 | } 15 | 16 | public override string ToString() 17 | { 18 | if (string.IsNullOrEmpty(Destination)) 19 | return Name; 20 | else 21 | return string.Format("{0} -> {1}", Name, Destination); 22 | 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Group.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class Group 6 | { 7 | 8 | [JsonPropertyName("group_id")] 9 | public int GroupId { get; set; } 10 | 11 | [JsonPropertyName("name")] 12 | public string Name { get; set; } 13 | 14 | [JsonPropertyName("published")] 15 | public bool Published { get; set; } 16 | 17 | [JsonPropertyName("category_id")] 18 | public int CategoryId { get; set; } 19 | 20 | [JsonPropertyName("types")] 21 | public int[] Types { get; set; } 22 | 23 | [JsonConstructor] 24 | public Group(int groupId, string name, bool published, int categoryId, int[] types) => 25 | (GroupId, Name, Published, CategoryId, Types) = (groupId, name, published, categoryId, types); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/CustomNode/EveSystemLink.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using WHMapper.Models.Custom.Node; 3 | using WHMapper.Models.Db.Enums; 4 | using WHMapper.Services.WHColor; 5 | 6 | namespace WHMapper.Components.Pages.Mapper.CustomNode; 7 | 8 | public partial class EveSystemLink 9 | { 10 | private const string DEFAULT_COLOR = IWHColorHelper.DEFAULT_COLOR; 11 | private string? _eolColor; 12 | 13 | 14 | [Inject] 15 | private IWHColorHelper? WHColorHelper { get; set; } 16 | 17 | 18 | [Parameter] 19 | public EveSystemLinkModel Link {get;set;}=null!; 20 | 21 | protected override Task OnParametersSetAsync() 22 | { 23 | if (Link != null) 24 | { 25 | _eolColor = WHColorHelper?.GetLinkEOLColor(Link.EndOfLifeStatus); 26 | } 27 | return base.OnParametersSetAsync(); 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20231204092305_AddSystemStatusToWHNote.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace WHMapper.Migrations 6 | { 7 | /// 8 | public partial class AddSystemStatusToWHNote : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.AddColumn( 14 | name: "SystemStatus", 15 | table: "Notes", 16 | type: "integer", 17 | nullable: false, 18 | defaultValue: 0); 19 | } 20 | 21 | /// 22 | protected override void Down(MigrationBuilder migrationBuilder) 23 | { 24 | migrationBuilder.DropColumn( 25 | name: "SystemStatus", 26 | table: "Notes"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHRoute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace WHMapper; 4 | 5 | public class WHRoute 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | 11 | public int? EveEntityId { get; set; } 12 | 13 | [Required] 14 | public int MapId { get; set; } 15 | 16 | [Required] 17 | public int SolarSystemId { get; set; } 18 | 19 | [Obsolete("EF Requires it")] 20 | protected WHRoute() { } 21 | 22 | public WHRoute(int mapId,int solarSystemId) 23 | { 24 | MapId = mapId; 25 | SolarSystemId = solarSystemId; 26 | } 27 | 28 | public WHRoute(int mapid,int solarSystemId,int eveEntityId) 29 | { 30 | MapId = mapid; 31 | EveEntityId = eveEntityId; 32 | SolarSystemId = solarSystemId; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/StargateEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Universe; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 6 | 7 | public class StargateEntity : AEveEntity 8 | { 9 | public int DestinationId { get; private set; } 10 | public int SourceId { get; private set; } 11 | 12 | public StargateEntity(int id, Stargate entity) 13 | : base(id, entity.Name, EveEntityEnums.Stargate) 14 | { 15 | DestinationId = entity.Destination.SystemId; 16 | SourceId = entity.SystemId; 17 | } 18 | 19 | [JsonConstructor] 20 | public StargateEntity(int id, string name, int destinationId, int sourceId) 21 | : base(id, name, EveEntityEnums.Stargate) 22 | { 23 | DestinationId = destinationId; 24 | SourceId = sourceId; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /deploy/docker/haproxy/docker-compose.yml: -------------------------------------------------------------------------------- 1 | 2 | services: 3 | haproxy: 4 | image: haproxy:latest 5 | user: root 6 | ports: 7 | - 80:80 8 | - 443:443 9 | volumes: 10 | - ./conf:/usr/local/etc/haproxy/:ro 11 | - ./certs:/usr/local/etc/certs:ro 12 | networks: 13 | - net 14 | - eve-whmapper_net 15 | 16 | nginx-certbot: 17 | image: nginx:latest 18 | restart: always 19 | container_name: nginx-certbot 20 | volumes: 21 | - ./nginx/:/etc/nginx/conf.d/:ro 22 | - ./certbot/www/:/var/www/certbot:ro 23 | - ./certbot/conf/:/etc/nginx/ssl/:ro 24 | networks: 25 | - net 26 | certbot: 27 | image: certbot/certbot:latest 28 | volumes: 29 | - ./certbot/www/:/var/www/certbot/:rw 30 | - ./certbot/conf/:/etc/letsencrypt/:rw 31 | networks: 32 | - net 33 | 34 | networks: 35 | net: 36 | driver: bridge 37 | eve-whmapper_net: 38 | external: true 39 | 40 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20250626204448_Add_WHSystem_AlternateName.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace WHMapper.Migrations 6 | { 7 | /// 8 | public partial class Add_WHSystem_AlternateName : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.AddColumn( 14 | name: "AlternateName", 15 | table: "Systems", 16 | type: "character varying(255)", 17 | maxLength: 255, 18 | nullable: true); 19 | } 20 | 21 | /// 22 | protected override void Down(MigrationBuilder migrationBuilder) 23 | { 24 | migrationBuilder.DropColumn( 25 | name: "AlternateName", 26 | table: "Systems"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/ConstellationEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveAPI.Universe; 3 | using WHMapper.Models.DTO.EveMapper.Enums; 4 | 5 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 6 | 7 | public class ConstellationEntity : AEveEntity 8 | { 9 | 10 | public int RegionId { get; private set; } 11 | public int[] Systems { get; private set; } 12 | 13 | public ConstellationEntity(int id, Constellation constellation) 14 | : base(id, constellation.Name, EveEntityEnums.Constellation) 15 | { 16 | RegionId = constellation.RegionId; 17 | Systems = constellation.Systems; 18 | } 19 | 20 | [JsonConstructor] 21 | public ConstellationEntity(int id, string name, int regionId, int[] systems) 22 | : base(id, name, EveEntityEnums.Constellation) 23 | { 24 | RegionId = regionId; 25 | Systems = systems; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /deploy/docker/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Require script to be run via sudo, but not as root 4 | 5 | if [[ $EUID != 0 ]]; then 6 | echo "Script must be run with root privilages!" 7 | exit 1 8 | elif [[ $EUID = $UID && "$SUDO_USER" = "" ]]; then 9 | echo "Script must be run as current user via 'sudo', not as the root user!" 10 | exit 1 11 | fi 12 | 13 | set -e 14 | 15 | #clear screen 16 | clear 17 | 18 | #check prerequisites 19 | if ! command -v docker &> /dev/null 20 | then 21 | echo "Docker could not be found. Please install Docker and try again." 22 | exit 1 23 | fi 24 | 25 | if ! command -v docker-compose &> /dev/null 26 | then 27 | echo "Docker-compose could not be found. Please install Docker-compose and try again." 28 | exit 1 29 | fi 30 | 31 | echo "Stoping..." 32 | echo "Stoping backend..." 33 | docker-compose -f ./eve-whmapper/docker-compose.yml stop 34 | 35 | echo "Stoping frontend..." 36 | docker-compose -f ./haproxy/docker-compose.yml stop 37 | -------------------------------------------------------------------------------- /deploy/docker/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Require script to be run via sudo, but not as root 4 | 5 | if [[ $EUID != 0 ]]; then 6 | echo "Script must be run with root privilages!" 7 | exit 1 8 | elif [[ $EUID = $UID && "$SUDO_USER" = "" ]]; then 9 | echo "Script must be run as current user via 'sudo', not as the root user!" 10 | exit 1 11 | fi 12 | 13 | set -e 14 | 15 | #clear screen 16 | clear 17 | 18 | #check prerequisites 19 | if ! command -v docker &> /dev/null 20 | then 21 | echo "Docker could not be found. Please install Docker and try again." 22 | exit 1 23 | fi 24 | 25 | if ! command -v docker-compose &> /dev/null 26 | then 27 | echo "Docker-compose could not be found. Please install Docker-compose and try again." 28 | exit 1 29 | fi 30 | 31 | echo "Starting..." 32 | echo "Starting backend..." 33 | docker-compose -f ./eve-whmapper/docker-compose.yml start 34 | 35 | echo "Starting frontend..." 36 | docker-compose -f ./haproxy/docker-compose.yml start 37 | -------------------------------------------------------------------------------- /deploy/kubernetes/deploys/frontend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: evemapper-app 5 | namespace: evemapper 6 | labels: 7 | order: "10" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | component: evemapper-app 13 | template: 14 | metadata: 15 | labels: 16 | component: evemapper-app 17 | spec: 18 | containers: 19 | - name: evemapper-app 20 | image: ghcr.io/pfh59/eve-whmapper:latest 21 | envFrom: 22 | - configMapRef: 23 | name: evemapper-config-map 24 | - secretRef: 25 | name: evemapper-secrets 26 | --- 27 | apiVersion: v1 28 | kind: Service 29 | metadata: 30 | name: evemapper-app-service 31 | namespace: evemapper 32 | labels: 33 | order: "11" 34 | spec: 35 | type: ClusterIP 36 | selector: 37 | component: evemapper-app 38 | ports: 39 | - name: port-0 40 | port: 8080 41 | targetPort: 8080 42 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Characters/CharacterServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Character; 3 | 4 | namespace WHMapper.Services.EveAPI.Characters 5 | { 6 | public class CharacterServices : EveApiServiceBase, ICharacterServices 7 | { 8 | public CharacterServices(HttpClient httpClient) 9 | : base(httpClient) 10 | { 11 | } 12 | 13 | public async Task> GetCharacter(int character_id) 14 | { 15 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, string.Format("/v5/characters/{0}/?datasource=tranquility", character_id)); 16 | } 17 | 18 | public async Task> GetCharacterPortrait(int character_id) 19 | { 20 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, string.Format("/v3/characters/{0}/portrait/?datasource=tranquility", character_id)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Star.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class Star 6 | { 7 | [JsonPropertyName("name")] 8 | public string Name { get; set; } = string.Empty; 9 | 10 | [JsonPropertyName("solar_system_id")] 11 | public int SolarSystemId { get; set; } 12 | 13 | [JsonPropertyName("type_id")] 14 | public int TypeId { get; set; } 15 | 16 | [JsonPropertyName("age")] 17 | public long Age { get; set; } 18 | 19 | [JsonPropertyName("luminosity")] 20 | public decimal Luminosity { get; set; } 21 | 22 | [JsonPropertyName("radius")] 23 | public long Radius { get; set; } 24 | 25 | [JsonPropertyName("spectral_class")] 26 | public string SpectralClass { get; set; } = string.Empty; 27 | 28 | [JsonPropertyName("temperature")] 29 | public int Temperature { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHAccess.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using WHMapper.Models.Db.Enums; 3 | 4 | namespace WHMapper.Models.Db 5 | { 6 | public class WHAccess 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | [Required] 12 | public int EveEntityId { get; set; } 13 | 14 | [Required] 15 | public string EveEntityName { get; set; }=string.Empty; 16 | 17 | [Required] 18 | public WHAccessEntity EveEntity { get; set; } 19 | 20 | public WHAccess() { } 21 | public WHAccess(int eveEntityId,string eveEntityName) : this(eveEntityId, eveEntityName, WHAccessEntity.Character) 22 | { 23 | 24 | } 25 | 26 | public WHAccess(int eveEntityId,string eveEntityName, WHAccessEntity entityType) 27 | { 28 | EveEntityId = eveEntityId; 29 | EveEntityName = eveEntityName; 30 | EveEntity = entityType; 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/EVEOnlineAuthenticationOptions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication.OAuth; 2 | 3 | namespace WHMapper.Services.EveOAuthProvider 4 | { 5 | public class EVEOnlineAuthenticationOptions : OAuthOptions 6 | { 7 | public string RevokeTokenEndpoint { get; private set; } = default!; 8 | public string JWKEndpoint { get; private set; } = default!; 9 | 10 | public EVEOnlineAuthenticationOptions() 11 | { 12 | ClaimsIssuer = EVEOnlineAuthenticationDefaults.Issuer; 13 | CallbackPath = EVEOnlineAuthenticationDefaults.CallbackPath; 14 | 15 | AuthorizationEndpoint = EVEOnlineAuthenticationDefaults.AuthorizationEndpoint; 16 | TokenEndpoint = EVEOnlineAuthenticationDefaults.TokenEndpoint; 17 | RevokeTokenEndpoint = EVEOnlineAuthenticationDefaults.RevokeTokenEndpoint; 18 | JWKEndpoint = EVEOnlineAuthenticationDefaults.JWKEndpoint; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WHMapper/Services/WHSignatures/IWHSignatureHelper.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper; 2 | 3 | namespace WHMapper.Services.WHSignature 4 | { 5 | public interface IWHSignatureHelper 6 | { 7 | const string SCAN_VALIDATION_REGEX = @"[A-Z]{3}-\d{3}\s+[\S\s]+?\s+\d*(,|.)\d+\s*\S*%(\s+\d{1,3}(?:['\s]\d{3})*(?:(,|.)\d{1,2})?\s(?:UA|AU|km|m|а\.е\.|AE|км|м))*"; 8 | Task ValidateScanResult(string? scanResult); 9 | Task?> ParseScanResult(string scanUser, int currentSystemScannedId, string? scanResult); 10 | Task ImportScanResult(string scanUser, int currentSystemScannedId, string? scanResult, bool lazyDeleted); 11 | Task?> GetCurrentSystemSignatures(int whId); 12 | Task?> AnalyzedSignatures(IEnumerable? parsedSigs,IEnumerable? currentSystemSigs , bool lazyDeleted); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: pfh59 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Universe/IUniverseServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Universe; 3 | 4 | namespace WHMapper.Services.EveAPI.Universe 5 | { 6 | public interface IUniverseServices 7 | { 8 | Task> GetSystems(); 9 | Task> GetSystem(int system_id); 10 | Task> GetStar(int star_id); 11 | Task> GetGroup(int group_id); 12 | Task> GetGroups(); 13 | Task> GetCategory(int category_id); 14 | Task> GetCategories(); 15 | Task> GetType(int type_id); 16 | Task> GetTypes(); 17 | Task> GetStargate(int stargate_id); 18 | Task> GetContellations(); 19 | Task> GetConstellation(int constellatio_id); 20 | Task> GetRegions(); 21 | Task> GetRegion(int region_id); 22 | } 23 | } -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Administration/Map/AddAccess.razor: -------------------------------------------------------------------------------- 1 | @using MudBlazor 2 | @using WHMapper.Models.Db; 3 | 4 | 5 | 6 | 7 | 8 | 9 | @if(_accesses != null) 10 | { 11 | foreach(WHAccess item in _accesses) 12 | { 13 | @item.EveEntityName 14 | } 15 | } 16 | 17 | 18 | 19 | 20 | Cancel 21 | Add Map Access 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/WHMapper/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official ASP.NET runtime as a parent image 2 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS base 3 | WORKDIR /app 4 | EXPOSE 80 5 | EXPOSE 443 6 | 7 | 8 | 9 | # Use the official .NET SDK as a parent image for building the application 10 | FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 11 | WORKDIR /src 12 | COPY ["WHMapper.csproj", "."] 13 | RUN dotnet restore "WHMapper.csproj" 14 | COPY . . 15 | RUN dotnet build "WHMapper.csproj" -c Release -o /app/build 16 | 17 | # Publish the application 18 | FROM build AS publish 19 | ARG VERSION=0.0.0 20 | RUN dotnet publish "WHMapper.csproj" -c Release -o /app/publish /p:Version=$VERSION 21 | 22 | # Final stage: use the runtime image to run the application 23 | FROM base AS final 24 | WORKDIR /app 25 | COPY --from=publish /app/publish . 26 | 27 | RUN rm -rf /src /app/build /app/publish && \ 28 | addgroup -S appgroup && adduser -S appuser -G appgroup && \ 29 | chown -R appuser:appgroup /app && \ 30 | chmod -R u+rw /app 31 | USER appuser 32 | 33 | ENTRYPOINT ["dotnet", "WHMapper.dll"] -------------------------------------------------------------------------------- /deploy/kubernetes/deploys/envs.yaml: -------------------------------------------------------------------------------- 1 | 2 | ################################## 3 | ### ConfigMap 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: evemapper-config-map 8 | namespace: evemapper 9 | labels: 10 | order: "4" 11 | data: 12 | DOMAIN: [your SUB/DOMAIN] 13 | POSTGRES_DB: [your db name] 14 | POSTGRESQL_USERNAME: [your db user] 15 | POSTGRESQL_PASSWORD: [your db password] 16 | POSTGRESQL_DATABASE: [your db name] 17 | EveSSO__ClientId: [your ccp app's client id] 18 | EveSSO__Secret: [your ccp app's secrect] 19 | ConnectionStrings__DatabaseConnection: server=[your master cluster IP];port=31252;database=[your db name];User Id=[your db user];Password=[your db password] 20 | ConnectionStrings__RedisConnection: [your master cluster IP]:31253 21 | Logging__LogLevel__Default: Warning 22 | Logging__LogLevel__Microsoft.EntityFrameworkCore.Database.Command: Warning 23 | --- 24 | 25 | ################################## 26 | ### Secrets 27 | apiVersion: v1 28 | kind: Secret 29 | metadata: 30 | name: evemapper-secrets 31 | namespace: evemapper 32 | labels: 33 | order: "5" 34 | --- 35 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Stargate.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | 6 | public class Stargate 7 | { 8 | [JsonPropertyName("stargate_id")] 9 | public required int StargateId { get; set; } 10 | 11 | [JsonPropertyName("name")] 12 | public required string Name { get; set; } 13 | 14 | [JsonPropertyName("type_id")] 15 | public required int TypeId { get; set; } 16 | 17 | [JsonPropertyName("position")] 18 | public required Position Position { get; set; } 19 | 20 | [JsonPropertyName("system_id")] 21 | public required int SystemId { get; set; } 22 | 23 | [JsonPropertyName("destination")] 24 | public required Destination Destination { get; set; } 25 | } 26 | 27 | public class Destination 28 | { 29 | [JsonPropertyName("system_id")] 30 | public required int SystemId { get; set; } 31 | 32 | [JsonPropertyName("stargate_id")] 33 | public required int StargateId { get; set; } 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 pfh59 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/WHMapper/Services/SDE/SdeDataSupplier.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.SDE 2 | { 3 | public class SdeDataSupplier : ISDEDataSupplier 4 | { 5 | private readonly ILogger _logger; 6 | private readonly HttpClient _httpClient; 7 | 8 | public SdeDataSupplier(ILogger logger, HttpClient httpClient) 9 | { 10 | _logger = logger; 11 | _httpClient = httpClient; 12 | } 13 | 14 | public string GetChecksum() 15 | { 16 | try 17 | { 18 | var checksum = _httpClient.GetStringAsync("checksum").Result; 19 | _logger.LogInformation($"Retrieved checksum: {checksum}"); 20 | return checksum; 21 | } 22 | catch (Exception ex) 23 | { 24 | _logger.LogWarning($"Couldn't retrieve checksum: {ex}"); 25 | } 26 | return string.Empty; 27 | } 28 | 29 | public Task GetSDEDataStreamAsync() 30 | { 31 | return _httpClient.GetStreamAsync("sde.zip"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information", 7 | "Microsoft.EntityFrameworkCore.Database.Command": "Information", 8 | "Microsoft.AspNetCore.DataProtection": "Information" 9 | } 10 | }, 11 | "AllowedHosts": "*", 12 | "EveSSO": { 13 | "Domain": "login.eveonline.com", 14 | "ClientId": "", 15 | "Secret": "", 16 | "DefaultScopes": [ 17 | "esi-location.read_location.v1", 18 | "esi-location.read_ship_type.v1", 19 | "esi-ui.open_window.v1", 20 | "esi-ui.write_waypoint.v1", 21 | "esi-search.search_structures.v1" 22 | ] 23 | }, 24 | "ConnectionStrings": { 25 | "DatabaseConnection": "server=localhost;port=5432;database=whmapper;User Id=postgres;Password=secret", 26 | "RedisConnection": "localhost:6379" 27 | }, 28 | "AnoikDataSupplier": { 29 | "JsonFilePath": "./Resources/Anoik/static.json" 30 | }, 31 | "SdeDataSupplier": { 32 | "BaseUrl": "https://eve-static-data-export.s3-eu-west-1.amazonaws.com/tranquility/" 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/AuthorizationPolicies/EveMapperAdminHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using System.Security.Claims; 3 | 4 | namespace WHMapper.Services.EveMapper.AuthorizationPolicies 5 | { 6 | public class EveMapperAdminHandler : AuthorizationHandler 7 | { 8 | private readonly IEveMapperAccessHelper _eveMapperAccessHelper; 9 | 10 | public EveMapperAdminHandler(IEveMapperAccessHelper eveMapperAccessHelper) 11 | { 12 | _eveMapperAccessHelper = eveMapperAccessHelper; 13 | } 14 | 15 | protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, EveMapperAdminRequirement requirement) 16 | { 17 | var characterId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; 18 | 19 | if (string.IsNullOrEmpty(characterId)) 20 | return; 21 | 22 | if (await _eveMapperAccessHelper.IsEveMapperAdminAccessAuthorized(Convert.ToInt32(characterId))) 23 | context.Succeed(requirement); 24 | 25 | return; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/WHMapper/Services/BrowserClientIdProvider/Extension/BrowserClientIdCookieMiddleware.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.BrowserClientIdProvider.Extension; 2 | 3 | public class BrowserClientIdCookieMiddleware 4 | { 5 | private readonly RequestDelegate _next; 6 | 7 | public BrowserClientIdCookieMiddleware(RequestDelegate next) 8 | { 9 | _next = next; 10 | } 11 | 12 | public async Task InvokeAsync(HttpContext context) 13 | { 14 | if (!context.Request.Cookies.ContainsKey("client_uid") && !context.Response.HasStarted) 15 | { 16 | var uid = Guid.NewGuid().ToString(); 17 | 18 | var cookieOptions = new CookieOptions 19 | { 20 | HttpOnly = true, 21 | SameSite = SameSiteMode.Lax, 22 | Path = "/", 23 | Expires = DateTimeOffset.UtcNow.AddYears(1), 24 | Secure = context.Request.IsHttps // Always set Secure based on HTTPS 25 | }; 26 | 27 | context.Response.Cookies.Append("client_uid", uid, cookieOptions); 28 | } 29 | 30 | await _next(context); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/AuthorizationPolicies/EveMapperAccessHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using System.Security.Claims; 3 | 4 | namespace WHMapper.Services.EveMapper.AuthorizationPolicies 5 | { 6 | public class EveMapperAccessHandler : AuthorizationHandler 7 | { 8 | 9 | private readonly IEveMapperAccessHelper _eveMapperAccessHelper; 10 | 11 | public EveMapperAccessHandler(IEveMapperAccessHelper eveMapperAccessHelper) 12 | { 13 | _eveMapperAccessHelper = eveMapperAccessHelper; 14 | } 15 | 16 | protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, EveMapperAccessRequirement requirement) 17 | { 18 | var characterId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; 19 | 20 | if (string.IsNullOrEmpty(characterId)) 21 | return; 22 | 23 | if (await _eveMapperAccessHelper.IsEveMapperUserAccessAuthorized(Convert.ToInt32(characterId))) 24 | context.Succeed(requirement); 25 | 26 | return; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperSearch.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper.EveEntity; 2 | using WHMapper.Models.DTO.SDE; 3 | 4 | namespace WHMapper.Services.EveMapper 5 | { 6 | public interface IEveMapperSearch 7 | { 8 | public const int MIN_SEARCH_SYSTEM_CHARACTERS = 3; 9 | public const int MIN_SEARCH_ENTITY_CHARACTERS = 5; 10 | 11 | Task?> SearchSystem(string value, CancellationToken cancellationToken); 12 | 13 | Task?> SearchCharactere(string value, CancellationToken cancellationToken); 14 | Task?> SearchCharactere(string value,bool strict, CancellationToken cancellationToken); 15 | Task?> SearchCorporation(string value,bool strict, CancellationToken cancellationToken); 16 | Task?> SearchAlliance(string value,bool strict, CancellationToken cancellationToken); 17 | Task?> SearchEveEntities(string value, CancellationToken cancellationToken); 18 | IEnumerable ValidateSearchType(string value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveCookieExtensions/EveCookieServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication.Cookies; 2 | using Microsoft.IdentityModel.Protocols.OpenIdConnect; 3 | using System; 4 | using WHMapper.Services.EveOAuthProvider; 5 | 6 | namespace WHMapper.Services.EveCookieExtensions; 7 | 8 | internal static partial class EveCookieServiceCollectionExtensions 9 | { 10 | public static IServiceCollection ConfigureEveCookieRefresh(this IServiceCollection services, string eveCookieScheme, string eveScheme) 11 | { 12 | services.AddSingleton(); 13 | services.AddOptions(eveCookieScheme) 14 | .Configure((eveCookieOptions, refresher) => 15 | { 16 | eveCookieOptions.Events.OnValidatePrincipal = context => refresher.ValidateOrRefreshCookieAsync(context, eveScheme); 17 | }); 18 | services.AddOptions(eveScheme).Configure(eveOptions => 19 | { 20 | // Store the refresh_token. 21 | eveOptions.SaveTokens = true; 22 | }); 23 | return services; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/SystemEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveMapper.Enums; 3 | 4 | namespace WHMapper.Models.DTO.EveMapper.EveEntity 5 | { 6 | public class SystemEntity : AEveEntity 7 | { 8 | public int ConstellationId { get; private set; } 9 | public float SecurityStatus { get; private set; } 10 | public int [] Stargates { get; private set; } 11 | 12 | public SystemEntity(int id, Models.DTO.EveAPI.Universe.ESISolarSystem entity) 13 | : base(id, entity.Name, EveEntityEnums.System) 14 | { 15 | SecurityStatus = entity.SecurityStatus; 16 | Stargates = entity.Stargates; 17 | ConstellationId = entity.ConstellationId; 18 | } 19 | 20 | [JsonConstructor] 21 | public SystemEntity(int id, string name,int constellationId,float securityStatus,int[] stargates) 22 | : base(id, name, EveEntityEnums.System) 23 | { 24 | SecurityStatus = securityStatus; 25 | Stargates = stargates; 26 | ConstellationId = constellationId; 27 | } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Search/SearchSystem.razor: -------------------------------------------------------------------------------- 1 | @using WHMapper.Models.DTO.SDE 2 | 3 | 4 | 5 | 6 | 14 | 15 | 16 | 17 | Cancel 18 | Add System 19 | 20 | 21 | -------------------------------------------------------------------------------- /deploy/localhost/docker/start.ps1: -------------------------------------------------------------------------------- 1 | # Require script to be run via elevated privileges, but not as Administrator 2 | 3 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 4 | Write-Host "Script must be run with elevated privileges!" 5 | exit 1 6 | } 7 | 8 | # Clear console 9 | Clear-Host 10 | 11 | # change script directory as working directory 12 | Set-Location -Path $PSScriptRoot 13 | 14 | 15 | # check prerequisites 16 | $docker = Get-Command -Name "docker" -ErrorAction SilentlyContinue 17 | $dockerCompose = Get-Command -Name "docker-compose" -ErrorAction SilentlyContinue 18 | 19 | if (-not $docker) { 20 | Write-Host "Error: Docker is not installed" -ForegroundColor Red 21 | exit 1 22 | } 23 | 24 | if (-not $dockerCompose) { 25 | Write-Host "Error: Docker Compose is not installed" -ForegroundColor Red 26 | exit 1 27 | } 28 | 29 | 30 | Write-Host "Starting..." 31 | docker compose start 32 | 33 | if ($LASTEXITCODE -ne 0) { 34 | Write-Host "Error: Docker compose failed to start containers" -ForegroundColor Red 35 | exit 1 36 | } 37 | 38 | Write-Host "Done." 39 | 40 | 41 | -------------------------------------------------------------------------------- /deploy/localhost/docker/stop.ps1: -------------------------------------------------------------------------------- 1 | # Require script to be run via elevated privileges, but not as Administrator 2 | 3 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 4 | Write-Host "Script must be run with elevated privileges!" 5 | exit 1 6 | } 7 | 8 | # Clear console 9 | Clear-Host 10 | 11 | # change script directory as working directory 12 | Set-Location -Path $PSScriptRoot 13 | 14 | 15 | # check prerequisites 16 | $docker = Get-Command -Name "docker" -ErrorAction SilentlyContinue 17 | $dockerCompose = Get-Command -Name "docker-compose" -ErrorAction SilentlyContinue 18 | 19 | if (-not $docker) { 20 | Write-Host "Error: Docker is not installed" -ForegroundColor Red 21 | exit 1 22 | } 23 | 24 | if (-not $dockerCompose) { 25 | Write-Host "Error: Docker Compose is not installed" -ForegroundColor Red 26 | exit 1 27 | } 28 | 29 | 30 | Write-Host "Stopping..." 31 | docker compose stop 32 | 33 | if ($LASTEXITCODE -ne 0) { 34 | Write-Host "Error: Docker compose failed to stop containers" -ForegroundColor Red 35 | exit 1 36 | } 37 | 38 | Write-Host "Done." 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperCacheService.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper.EveEntity; 2 | 3 | namespace WHMapper.Services.EveMapper 4 | { 5 | public interface IEveMapperCacheService 6 | { 7 | const string REDIS_ALLIANCE_KEY = "alliance:list"; 8 | const string REDIS_COORPORATION_KEY = "coorporation:list"; 9 | const string REDIS_CHARACTER_KEY = "charactere:list"; 10 | const string REDIS_SHIP_KEY = "ship:list"; 11 | const string REDIS_SYSTEM_KEY = "system:list"; 12 | const string REDIS_CONSTELLATION_KEY = "constellation:list"; 13 | const string REDIS_REGION_KEY = "region:list"; 14 | const string REDIS_STARTGATE_KEY = "stargate:list"; 15 | const string REDIS_GROUP_KEY = "group:list"; 16 | const string REDIS_WORMHOLE_KEY = "wormhole:list"; 17 | const string REDIS_SUN_KEY = "sun:list"; 18 | 19 | Task GetAsync(int key) 20 | where TEntity : AEveEntity; 21 | 22 | Task AddAsync(TEntity entity) 23 | where TEntity : AEveEntity; 24 | 25 | Task ClearCacheAsync() 26 | where TEntity : AEveEntity; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/Planet.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class Planet 6 | { 7 | [JsonPropertyName("planet_id")] 8 | public int PlanetId { get; private set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string Name { get; private set; } 12 | 13 | [JsonPropertyName("type_id")] 14 | public int TypeId { get; private set; } 15 | 16 | [JsonPropertyName("position")] 17 | public Position Position { get; private set; } 18 | 19 | [JsonPropertyName("system_id")] 20 | public int SystemId { get; private set; } 21 | 22 | 23 | [JsonPropertyName("asteroid_belts")] 24 | public int[] AsteroidBelts { get; private set; } 25 | 26 | [JsonPropertyName("moons")] 27 | public int[] Moons { get; private set; } 28 | 29 | [JsonConstructor] 30 | public Planet(int planetId,string name, int typeId, Position pos,int systemId,int[] asteroidBelts,int[] moons) => 31 | (PlanetId,Name, TypeId, Position, SystemId, AsteroidBelts, Moons) = (planetId, name, typeId, pos, systemId, asteroidBelts, moons); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/WHMapper/Services/BrowserClientIdProvider/BrowserClientIdProvider.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.BrowserClientIdProvider; 2 | 3 | public class BrowserClientIdProvider : IBrowserClientIdProvider 4 | { 5 | private readonly ILogger _logger; 6 | private readonly IHttpContextAccessor _httpContextAccessor; 7 | public BrowserClientIdProvider(ILogger logger, IHttpContextAccessor httpContextAccessor) 8 | { 9 | _logger = logger; 10 | _httpContextAccessor = httpContextAccessor; 11 | } 12 | 13 | public Task GetClientIdAsync() 14 | { 15 | var context = _httpContextAccessor.HttpContext; 16 | if (context == null) 17 | { 18 | _logger.LogError("HttpContext is null. Cannot access cookies."); 19 | return Task.FromResult(null); 20 | } 21 | 22 | if (context.Request.Cookies.ContainsKey("client_uid")) 23 | { 24 | // If the cookie exists, return its value 25 | return Task.FromResult(context.Request.Cookies["client_uid"]); 26 | } 27 | return Task.FromResult(null); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /deploy/docker/eve-whmapper/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | db: 3 | image: postgres:17-alpine 4 | restart: always 5 | environment: 6 | POSTGRES_USER: ${POSTGRES_USER:-postgres} 7 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secret} 8 | POSTGRES_DB: whmapper 9 | PGDATA: /data/postgres 10 | volumes: 11 | - postgres:/data/postgres 12 | networks: 13 | - net 14 | 15 | redis: 16 | image: redis:8-alpine 17 | restart: always 18 | networks: 19 | - net 20 | 21 | whmapper: 22 | image: ghcr.io/pfh59/eve-whmapper:latest 23 | restart: unless-stopped 24 | environment: 25 | - EveSSO__ClientId=xxxxxxxxx 26 | - EveSSO__Secret=xxxxxxxxx 27 | - ConnectionStrings__DatabaseConnection=server=db;port=5432;database=whmapper;User Id=postgres;Password=secret 28 | - ConnectionStrings__RedisConnection=redis:6379 29 | - Serilog__MinimumLevel__Default=Warning 30 | - Serilog__MinimumLevel__Override__Microsoft.EntityFrameworkCore.Database.Command=Warning 31 | links: 32 | - db 33 | depends_on: 34 | - db 35 | networks: 36 | - net 37 | volumes: 38 | - ./Logs:/app/Logs 39 | 40 | networks: 41 | net: 42 | 43 | volumes: 44 | postgres: -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/Services/EveUserInfosServices.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.Authorization; 2 | using System.Security.Claims; 3 | 4 | 5 | 6 | namespace WHMapper.Services.EveOAuthProvider.Services; 7 | 8 | public class EveUserInfosServices : IEveUserInfosServices 9 | { 10 | private readonly AuthenticationStateProvider _authenticationStateProvider; 11 | 12 | public EveUserInfosServices(AuthenticationStateProvider authenticationStateProvider) 13 | { 14 | _authenticationStateProvider = authenticationStateProvider; 15 | } 16 | 17 | public async Task GetUserName() 18 | { 19 | var state = await _authenticationStateProvider.GetAuthenticationStateAsync(); 20 | return state?.User?.Identity?.Name ?? IEveUserInfosServices.ANONYMOUS_USERNAME; 21 | 22 | } 23 | 24 | public async Task GetCharactedID() 25 | { 26 | var state = await _authenticationStateProvider.GetAuthenticationStateAsync(); 27 | var characterId = state?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; 28 | if (string.IsNullOrEmpty(characterId)) 29 | return 0; 30 | else 31 | return Convert.ToInt32(characterId); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Alliance/Alliance.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Alliance 4 | { 5 | public class Alliance 6 | { 7 | [JsonPropertyName("creator_corporation_id")] 8 | public int CreatorCorporationId { get; set; } 9 | 10 | [JsonPropertyName("creator_id")] 11 | public int CreatorId { get; set; } 12 | 13 | [JsonPropertyName("date_founded")] 14 | public DateTime DateFounded { get; set; } 15 | 16 | [JsonPropertyName("executor_corporation_id")] 17 | public int ExecutorCorporationId { get; set; } 18 | 19 | [JsonPropertyName("faction_id")] 20 | public int FactionId { get; set; } 21 | 22 | [JsonPropertyName("name")] 23 | public string Name { get; set; } = string.Empty; 24 | 25 | [JsonPropertyName("ticker")] 26 | public string Ticker { get; set; } = string.Empty; 27 | 28 | /* 29 | [JsonConstructor] 30 | public Alliance(int creatorCorporationIid, int creatorId, DateTime dateFounded,string name,string ticker) => 31 | (CreatorCorporationId, CreatorId, DateFounded, Name, Ticker) = (creatorCorporationIid, creatorId, dateFounded,name, ticker);*/ 32 | 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveRoute.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper; 2 | 3 | public class EveRoute 4 | { 5 | public int Id {get;private set;} 6 | public string DestinationName {get;private set;} 7 | public int[]? Route {get;private set;} 8 | 9 | public int RouteLength 10 | { 11 | get 12 | { 13 | if(Route == null) 14 | return 0; 15 | else 16 | { 17 | return Route.Length; 18 | } 19 | } 20 | } 21 | 22 | public int JumpLength 23 | { 24 | get 25 | { 26 | if(Route == null || Route.Length < 2) 27 | return 0; 28 | else 29 | { 30 | return Route.Length - 1; 31 | } 32 | } 33 | } 34 | 35 | public bool IsAvailable 36 | { 37 | get 38 | { 39 | return Route != null && Route.Length > 0; 40 | } 41 | } 42 | 43 | public bool IsShowed {get;set;} = false; 44 | 45 | public EveRoute(int id, string destinationName,int[]? route) 46 | { 47 | Id = id; 48 | DestinationName = destinationName; 49 | Route = route; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/IEveAPIServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Services.EveAPI.Alliances; 3 | using WHMapper.Services.EveAPI.Assets; 4 | using WHMapper.Services.EveAPI.Characters; 5 | using WHMapper.Services.EveAPI.Corporations; 6 | using WHMapper.Services.EveAPI.Dogma; 7 | using WHMapper.Services.EveAPI.Locations; 8 | using WHMapper.Services.EveAPI.Routes; 9 | using WHMapper.Services.EveAPI.Search; 10 | using WHMapper.Services.EveAPI.Universe; 11 | using WHMapper.Services.EveAPI.UserInterface; 12 | 13 | namespace WHMapper.Services.EveAPI 14 | { 15 | public interface IEveAPIServices 16 | { 17 | ILocationServices LocationServices { get; } 18 | IUniverseServices UniverseServices { get; } 19 | IUserInterfaceServices UserInterfaceServices { get; } 20 | IAllianceServices AllianceServices { get; } 21 | ICorporationServices CorporationServices { get; } 22 | ICharacterServices CharacterServices { get; } 23 | ISearchServices SearchServices { get; } 24 | IDogmaServices DogmaServices { get; } 25 | IRouteServices RouteServices { get; } 26 | IAssetsServices AssetsServices { get; } 27 | 28 | Task SetEveCharacterAuthenticatication(UserToken userToken); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Dogma/Attribute.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Dogma 4 | { 5 | public class Attribute 6 | { 7 | [JsonPropertyName("attribute_id")] 8 | public int AttributeId { get; set; } 9 | 10 | [JsonPropertyName("default_value")] 11 | public float DefaultValue { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string Description { get; set; } = string.Empty; 15 | 16 | [JsonPropertyName("display_name")] 17 | public string DisplayName { get; set; } = string.Empty; 18 | 19 | [JsonPropertyName("high_is_good")] 20 | public bool HighIsGood { get; set; } 21 | 22 | [JsonPropertyName("icon_id")] 23 | public int IconId { get; set; } 24 | 25 | [JsonPropertyName("name")] 26 | public string Name { get; set; } = string.Empty; 27 | 28 | [JsonPropertyName("published")] 29 | public bool Published { get; set; } 30 | 31 | [JsonPropertyName("stackable")] 32 | public bool Stackable { get; set; } 33 | 34 | [JsonPropertyName("unit_id")] 35 | public int UnitId { get; set; } 36 | 37 | 38 | public Attribute() 39 | { 40 | 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | All contributors are welcome to this project in the form of feedback, bug reports and even better pull requests. 4 | 5 | ## Issues 6 | 7 | Issues are used to track **bugs**, **feature requests**, and other work. 8 | 9 | _Before reporting a bug or requesting a feature, run a few searches to 10 | see if a similar issue has already been opened and ensure you’re not submitting 11 | a duplicate._ 12 | 13 | ### Bug reports 14 | 15 | * Describe steps to reproduce 16 | * Full error message if any 17 | * Your code if relevant 18 | 19 | _Of course you could propose a fix using pull request._ 20 | 21 | ## Pull Request Guidelines 22 | 23 | * Open a single Pull Request for each subject. 24 | * Prefer to develop in a topic branch, not in `main` (`feature/name`, `fix/name`). 25 | * Update documentation where applicable. 26 | * If any bug related, add `#` in commit message or pull request. 27 | 28 | ### Only touch relevant files 29 | 30 | * Make sure your PR stays focused on a single feature or category. 31 | * Don't change project configs or any files unrelated to the subject you're working. 32 | * Don't reformat code you don't modify. 33 | 34 | ## Licensing 35 | 36 | When submitting your first pull request, you will be asked to read the [CLA Document](CLA.md) and accept it. 37 | -------------------------------------------------------------------------------- /deploy/docker/start.ps1: -------------------------------------------------------------------------------- 1 | # Require script to be run via elevated privileges, but not as Administrator 2 | 3 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 4 | Write-Host "Script must be run with elevated privileges!" 5 | exit 1 6 | } 7 | 8 | # Clear console 9 | Clear-Host 10 | 11 | # check prerequisites 12 | $docker = Get-Command -Name "docker" -ErrorAction SilentlyContinue 13 | $dockerCompose = Get-Command -Name "docker-compose" -ErrorAction SilentlyContinue 14 | 15 | if (-not $docker) { 16 | Write-Host "Error: Docker is not installed" -ForegroundColor Red 17 | exit 1 18 | } 19 | 20 | if (-not $dockerCompose) { 21 | Write-Host "Error: Docker Compose is not installed" -ForegroundColor Red 22 | exit 1 23 | } 24 | 25 | 26 | Write-Host "Starting..." 27 | Write-Host "Starting backend..." 28 | if($IsWindows) { 29 | docker-compose -f .\eve-whmapper\docker-compose.yml start 30 | } else { 31 | docker-compose -f ./eve-whmapper/docker-compose.yml start 32 | } 33 | 34 | 35 | Write-Host "Starting frontend..." 36 | if($IsWindows) { 37 | docker-compose -f .\haproxy\docker-compose.yml start 38 | } else { 39 | docker-compose -f ./haproxy/docker-compose.yml start 40 | } -------------------------------------------------------------------------------- /deploy/docker/stop.ps1: -------------------------------------------------------------------------------- 1 | # Require script to be run via sudo, but not as root 2 | 3 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 4 | Write-Host "Script must be run with administrator privileges!" 5 | exit 1 6 | } 7 | # clear console 8 | Clear-Host 9 | 10 | # check prerequisites 11 | $docker = Get-Command -Name "docker" -ErrorAction SilentlyContinue 12 | $dockerCompose = Get-Command -Name "docker-compose" -ErrorAction SilentlyContinue 13 | 14 | if (-not $docker) { 15 | Write-Host "Error: Docker is not installed" -ForegroundColor Red 16 | exit 1 17 | } 18 | 19 | if (-not $dockerCompose) { 20 | Write-Host "Error: Docker Compose is not installed" -ForegroundColor Red 21 | exit 1 22 | } 23 | 24 | Write-Host "Stopping..." 25 | if($IsWindows) { 26 | Write-Host "Stopping backend..." 27 | docker-compose -f .\eve-whmapper\docker-compose.yml stop 28 | Write-Host "Stopping frontend..." 29 | docker-compose -f .\haproxy\docker-compose.yml stop 30 | } else { 31 | Write-Host "Stopping backend..." 32 | docker-compose -f ./eve-whmapper/docker-compose.yml stop 33 | Write-Host "Stopping frontend..." 34 | docker-compose -f ./haproxy/docker-compose.yml stop 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHJumpLog.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace WHMapper.Models.Db; 4 | 5 | public class WHJumpLog 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | [Required] 11 | public int WHSystemLinkId { get; set; } 12 | 13 | [Required] 14 | public int CharacterId { get; set; } 15 | 16 | [Required] 17 | public DateTime JumpDate { get; set; } 18 | 19 | public int? ShipTypeId { get; set; } 20 | 21 | public long? ShipItemId { get; set; } 22 | 23 | public float? ShipMass { get; set; } 24 | 25 | [Obsolete("EF Requires it")] 26 | protected WHJumpLog() { } 27 | 28 | //Construstor when lin k are create manually, no ship used 29 | public WHJumpLog(int linkId,int characterId) : 30 | this(linkId, characterId, null, null, null) 31 | { 32 | 33 | } 34 | 35 | //Constrtuctor for real jump with a real ship 36 | public WHJumpLog(int linkId,int characterId,int? shipTypeId, long? shipItemId, float? shipMass) 37 | { 38 | WHSystemLinkId=linkId; 39 | CharacterId = characterId; 40 | JumpDate = DateTime.UtcNow; 41 | ShipTypeId = shipTypeId; 42 | ShipItemId = shipItemId; 43 | ShipMass = shipMass; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Character/Character.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Character 4 | { 5 | public class Character 6 | { 7 | [JsonPropertyName("alliance_id")] 8 | public int AllianceId { get; set; } 9 | 10 | [JsonPropertyName("birthday")] 11 | public DateTime Birthday { get; set; } 12 | 13 | [JsonPropertyName("bloodline_id")] 14 | public int BloodlineId { get; set; } 15 | 16 | [JsonPropertyName("corporation_id")] 17 | public int CorporationId { get; set; } 18 | 19 | [JsonPropertyName("description")] 20 | public string Description { get; set; } = string.Empty; 21 | 22 | [JsonPropertyName("faction_id")] 23 | public int FactionId { get; set; } 24 | 25 | [JsonPropertyName("gender")] 26 | public string Gender { get; set; } = string.Empty; 27 | 28 | [JsonPropertyName("name")] 29 | public string Name { get; set; } = string.Empty; 30 | 31 | [JsonPropertyName("race_id")] 32 | public int RaceId { get; set; } 33 | 34 | [JsonPropertyName("security_status")] 35 | public float SecurityStatus { get; set; } 36 | 37 | [JsonPropertyName("title")] 38 | public string Title { get; set; } = string.Empty; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Assets/AssetsServices.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using WHMapper.Models.DTO; 3 | using WHMapper.Models.DTO.EveAPI.Assets; 4 | 5 | namespace WHMapper.Services.EveAPI.Assets 6 | { 7 | public class AssetsServices : EveApiServiceBase, IAssetsServices 8 | { 9 | public AssetsServices(HttpClient httpClient, UserToken? userToken = null) 10 | : base(httpClient, userToken) 11 | { 12 | } 13 | 14 | public async Task>> GetCharacterAssets(int character_id, int page = 1) 15 | { 16 | return await base.Execute>(RequestSecurity.Authenticated, RequestMethod.Get, string.Format("/v5/characters/{0}/assets/?datasource=tranquility&page{1}", character_id, page)); 17 | } 18 | 19 | public async Task>> GetMyAssets(int page = 1) 20 | { 21 | if (this.UserToken != null && UserToken.AccountId != null) 22 | { 23 | int character_id = Int32.Parse(UserToken.AccountId); 24 | return await GetCharacterAssets(character_id, page); 25 | } 26 | return Result>.Failure("UserToken is required for authenticated requests", (int)HttpStatusCode.Unauthorized); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/WHMapper.Tests/Models/UserTokenTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using WHMapper.Models.DTO; 4 | using Xunit; 5 | 6 | namespace WHMapper.Tests.Models; 7 | 8 | 9 | public class UserTokenTest 10 | { 11 | [Fact] 12 | public void UserToken_CanBeInstantiated() 13 | { 14 | var userToken = new UserToken(); 15 | Assert.NotNull(userToken); 16 | } 17 | 18 | [Fact] 19 | public void UserToken_Properties_CanBeSetAndRetrieved() 20 | { 21 | var userToken = new UserToken 22 | { 23 | AccountId = "12345", 24 | AccessToken = "access_token", 25 | RefreshToken = "refresh_token", 26 | Expiry = new DateTime(2023, 12, 31) 27 | }; 28 | 29 | Assert.Equal("12345", userToken.AccountId); 30 | Assert.Equal("access_token", userToken.AccessToken); 31 | Assert.Equal("refresh_token", userToken.RefreshToken); 32 | Assert.Equal(new DateTime(2023, 12, 31), userToken.Expiry); 33 | } 34 | 35 | [Fact] 36 | public void UserToken_Expiry_SetCorrectly() 37 | { 38 | var expiryDate = new DateTime(2023, 12, 31); 39 | var userToken = new UserToken 40 | { 41 | Expiry = expiryDate 42 | }; 43 | 44 | Assert.Equal(expiryDate, userToken.Expiry); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /deploy/kubernetes/deploys/base.yaml: -------------------------------------------------------------------------------- 1 | 2 | ################################## 3 | ### Namespace 4 | 5 | apiVersion: v1 6 | kind: Namespace 7 | metadata: 8 | name: evemapper 9 | labels: 10 | order: "1" 11 | --- 12 | 13 | ################################## 14 | ### Certificate issuer 15 | apiVersion: cert-manager.io/v1 16 | kind: Issuer 17 | metadata: 18 | name: letsencrypt-evemapper 19 | namespace: evemapper 20 | labels: 21 | order: "2" 22 | spec: 23 | acme: 24 | # The ACME server URL 25 | server: https://acme-v02.api.letsencrypt.org/directory 26 | # Email address used for ACME registration 27 | email: [your valid email] 28 | # Name of a secret used to store the ACME account private key 29 | privateKeySecretRef: 30 | name: letsencrypt-evemapper 31 | # Enable the HTTP-01 challenge provider 32 | solvers: 33 | - http01: 34 | ingress: 35 | ingressClassName: traefik 36 | --- 37 | 38 | ################################## 39 | ### Certificate 40 | apiVersion: cert-manager.io/v1 41 | kind: Certificate 42 | metadata: 43 | name: tls-evemapper 44 | namespace: evemapper 45 | labels: 46 | order: "3" 47 | spec: 48 | secretName: tls-evemapper 49 | commonName: [your SUB/DOMAIN] 50 | issuerRef: 51 | name: letsencrypt-evemapper 52 | kind: Issuer 53 | dnsNames: 54 | - [your SUB/DOMAIN] 55 | --- -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Error.razor: -------------------------------------------------------------------------------- 1 | @page "/Error" 2 | @using System.Diagnostics 3 | 4 | Error 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (ShowRequestId) 10 | { 11 |

12 | Request ID: @RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | 27 | @code{ 28 | [CascadingParameter] 29 | private HttpContext? HttpContext { get; set; } 30 | 31 | private string? RequestId { get; set; } 32 | private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 33 | 34 | protected override void OnInitialized() => 35 | RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; 36 | } 37 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/CustomDiagramSelectionBehavior.cs: -------------------------------------------------------------------------------- 1 | using Blazor.Diagrams.Core; 2 | using Blazor.Diagrams.Core.Events; 3 | using Blazor.Diagrams.Core.Models.Base; 4 | 5 | namespace WHMapper.Components.Pages.Mapper 6 | { 7 | public class CustomDiagramSelectionBehavior : Behavior 8 | { 9 | public CustomDiagramSelectionBehavior(Diagram diagram) : base(diagram) 10 | { 11 | 12 | Diagram.PointerDown += OnPointerDown; 13 | } 14 | 15 | 16 | private void OnPointerDown(Model? model, PointerEventArgs e) 17 | { 18 | if (e.Button==0) 19 | { 20 | if (model == null) 21 | { 22 | Diagram.UnselectAll(); 23 | } 24 | else if (model is SelectableModel sm) 25 | { 26 | if (e.CtrlKey && sm.Selected) 27 | { 28 | Diagram.UnselectModel(sm); 29 | } 30 | else if (!sm.Selected) 31 | { 32 | Diagram.SelectModel(sm, !e.CtrlKey || !Diagram.Options.AllowMultiSelection); 33 | } 34 | } 35 | } 36 | } 37 | 38 | public override void Dispose() 39 | { 40 | Diagram.PointerDown -= OnPointerDown; 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHNote.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using WHMapper.Models.Db.Enums; 3 | 4 | namespace WHMapper.Models.Db 5 | { 6 | public class WHNote 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | [Required] 12 | public int MapId { get; set; } = -1; 13 | 14 | [Required] 15 | public int SoloarSystemId { get; set; } = -1; 16 | 17 | [Required, StringLength(255, ErrorMessage = "Comment is too long.")] 18 | public String Comment { get; set; } = string.Empty; 19 | 20 | public WHSystemStatus SystemStatus { get; set; } = WHSystemStatus.Unknown; 21 | 22 | [Obsolete("EF Requires it")] 23 | protected WHNote() { } 24 | 25 | public WHNote(int mapId,int soloarSystemId,string comment) 26 | : this(mapId,soloarSystemId,WHSystemStatus.Unknown,comment) 27 | { 28 | 29 | } 30 | 31 | public WHNote(int mapId,int soloarSystemId, WHSystemStatus systemStatus) 32 | :this(mapId,soloarSystemId,systemStatus,string.Empty) 33 | 34 | { 35 | 36 | } 37 | 38 | public WHNote(int mapId,int soloarSystemId, WHSystemStatus systemStatus,string comment) 39 | { 40 | MapId = mapId; 41 | SoloarSystemId = soloarSystemId; 42 | SystemStatus = systemStatus; 43 | Comment = comment; 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/WHMapper/Services/Anoik/AnoikJsonDataSupplier.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace WHMapper.Services.Anoik 4 | { 5 | public class AnoikJsonDataSupplier : IAnoikDataSupplier 6 | { 7 | private readonly JsonDocument _json; 8 | 9 | public AnoikJsonDataSupplier(string jsonFilePath) 10 | { 11 | ArgumentNullException.ThrowIfNullOrWhiteSpace(jsonFilePath); 12 | 13 | try 14 | { 15 | string jsonText = File.ReadAllText(jsonFilePath); 16 | _json = JsonDocument.Parse(jsonText); 17 | } 18 | catch (FileNotFoundException ex) 19 | { 20 | throw new ArgumentException("The specified JSON file was not found.", nameof(jsonFilePath), ex); 21 | } 22 | catch (JsonException ex) 23 | { 24 | throw new ArgumentException("The JSON file is invalid or malformed.", nameof(jsonFilePath), ex); 25 | } 26 | } 27 | 28 | public JsonElement GetSystems() 29 | { 30 | return _json.RootElement.GetProperty("systems"); 31 | } 32 | 33 | public JsonElement GetEffects() 34 | { 35 | return _json.RootElement.GetProperty("effects"); 36 | } 37 | 38 | public JsonElement GetWormHoles() 39 | { 40 | return _json.RootElement.GetProperty("wormholes"); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Locations/LocationServices.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using WHMapper.Models.DTO; 3 | using WHMapper.Models.DTO.EveAPI.Location; 4 | 5 | namespace WHMapper.Services.EveAPI.Locations 6 | { 7 | public class LocationServices : EveApiServiceBase, ILocationServices 8 | { 9 | public LocationServices(HttpClient httpClient, UserToken? userToken = null) : base(httpClient, userToken) 10 | { 11 | } 12 | 13 | public async Task> GetLocation() 14 | { 15 | if (this.UserToken != null) 16 | { 17 | return await base.Execute(RequestSecurity.Authenticated, RequestMethod.Get, string.Format("/v2/characters/{0}/location/?datasource=tranquility", UserToken.AccountId)); 18 | } 19 | return Result.Failure("UserToken is required for authenticated requests", (int)HttpStatusCode.Unauthorized); 20 | } 21 | 22 | public async Task> GetCurrentShip() 23 | { 24 | if (this.UserToken != null) 25 | { 26 | return await base.Execute(RequestSecurity.Authenticated, RequestMethod.Get, string.Format("/v2/characters/{0}/ship/?datasource=tranquility", UserToken.AccountId)); 27 | } 28 | return Result.Failure("UserToken is required for authenticated requests", (int)HttpStatusCode.Unauthorized); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/WormholeType.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveMapper.Enums; 2 | using WHMapper.Models.DTO.EveMapper.EveEntity; 3 | 4 | namespace WHMapper.Models.DTO.EveMapper 5 | { 6 | public class WormholeType 7 | { 8 | public string Name { private set; get; } 9 | public EveSystemType Destination { private set; get; } 10 | 11 | public float MassMax {get; private set;} 12 | public float JumpMassMax {get; private set;} 13 | 14 | /// 15 | /// Time in minutes 16 | /// 24h = 1440 17 | /// 18h = 1080 18 | /// 19 | public float StableTime {get;private set;} 20 | 21 | public WormholeType(string name, EveSystemType dest) 22 | { 23 | Name = name; 24 | Destination = dest; 25 | } 26 | 27 | public WormholeType(WHEntity entity) 28 | { 29 | Name = entity.Name; 30 | Destination = (EveSystemType)entity.SystemTypeValue; 31 | MassMax = entity.MassMax; 32 | JumpMassMax = entity.JumpMassMax; 33 | StableTime = entity.StableTime; 34 | } 35 | 36 | 37 | public override string ToString() 38 | { 39 | if (string.IsNullOrEmpty(Destination.ToString())) 40 | return Name; 41 | else 42 | return string.Format("{0} -> {1}", Name, Destination); 43 | 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Dogma/DogmaServices.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using WHMapper.Models.DTO.EveAPI.Dogma; 3 | 4 | namespace WHMapper.Services.EveAPI.Dogma 5 | { 6 | public class DogmaServices : EveApiServiceBase, IDogmaServices 7 | { 8 | public DogmaServices(HttpClient httpClient, UserToken? userToken = null) : base(httpClient, userToken) 9 | { 10 | } 11 | 12 | public async Task> GetAttribute(int attribute_id) 13 | { 14 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, string.Format("/v1/dogma/attributes/{0}/?datasource=tranquility", attribute_id)); 15 | } 16 | 17 | public async Task> GetAttributes() 18 | { 19 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, "/v1/dogma/attributes/?datasource=tranquility"); 20 | } 21 | 22 | public async Task> GetEffect(int effect_id) 23 | { 24 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, string.Format("/v1/dogma/effects/{0}/?datasource=tranquility", effect_id)); 25 | } 26 | 27 | public async Task> GetEffects() 28 | { 29 | return await base.Execute(RequestSecurity.Public, RequestMethod.Get, "/v1/dogma/effects/?datasource=tranquility"); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/WHMapper.Tests/Services/Anoik/AnoikServiceTestConstants.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace WHMapper.Tests.Services.Anoik 4 | { 5 | public static class AnoikServiceTestConstants 6 | { 7 | public static string ValidJson = @" 8 | { 9 | ""systems"": { 10 | ""J120450"": { 11 | ""solarSystemID"": 31001554, 12 | ""wormholeClass"": ""C4"", 13 | ""effectName"": ""Red Giant"", 14 | ""statics"": [""H900"", ""X877""] 15 | } 16 | }, 17 | ""effects"": { 18 | ""Pulsar"": { 19 | ""Shield Capacity"": [""+30%"", ""+44%"", ""+58%"", ""+72%"", ""+86%"", ""+100%""] 20 | } 21 | }, 22 | ""wormholes"": { 23 | ""H900"": { 24 | ""dest"": ""C5"", 25 | ""src"": [""C4""] 26 | }, 27 | ""X877"": { 28 | ""dest"": ""C2"", 29 | ""src"": [""C3"", ""C4""] 30 | } 31 | } 32 | }"; 33 | 34 | public static JsonDocument GetJsonDocument() 35 | { 36 | return JsonDocument.Parse(ValidJson); 37 | } 38 | 39 | public static JsonElement GetElement(string name) 40 | { 41 | return GetJsonDocument().RootElement.GetProperty(name); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/WHMapper/Models/Db/WHSystemLink.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using WHMapper.Models.Db.Enums; 3 | 4 | namespace WHMapper.Models.Db 5 | { 6 | public class WHSystemLink 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | [Required] 12 | public int WHMapId { get; set; } 13 | 14 | [Required] 15 | public int IdWHSystemFrom { get; set; } 16 | 17 | [Required] 18 | public int IdWHSystemTo { get; set; } 19 | 20 | [Required] 21 | public SystemLinkEolStatus EndOfLifeStatus { get; set; } = SystemLinkEolStatus.Normal; 22 | 23 | [Required] 24 | public SystemLinkSize Size { get; set; } = SystemLinkSize.Large; 25 | 26 | [Required] 27 | public SystemLinkMassStatus MassStatus { get; set; } = SystemLinkMassStatus.Normal; 28 | 29 | [Required] 30 | public virtual ICollection JumpHistory { get; } = new HashSet(); 31 | 32 | 33 | [Obsolete("EF Requires it")] 34 | protected WHSystemLink() { } 35 | public WHSystemLink(int idWHSystemFrom, int idWHSystemTo) : 36 | this(0,idWHSystemFrom,idWHSystemTo) 37 | { 38 | } 39 | 40 | public WHSystemLink(int whMapId,int idWHSystemFrom, int idWHSystemTo) 41 | { 42 | WHMapId = whMapId; 43 | IdWHSystemFrom = idWHSystemFrom; 44 | IdWHSystemTo = idWHSystemTo; 45 | } 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/Enums/EveSystemTypeEnums.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Reflection; 3 | 4 | namespace WHMapper.Models.DTO.EveMapper.Enums 5 | { 6 | public enum EveSystemType :int 7 | { 8 | HS=7, 9 | LS=8, 10 | NS=9, 11 | [Description("T")] 12 | Pochven=25, 13 | C1=1, 14 | C2=2, 15 | C3=3, 16 | C4=4, 17 | C5=5, 18 | C6=6, 19 | C13=13, 20 | C14=14, 21 | C15=15, 22 | C16=16, 23 | C17=17, 24 | C18=18, 25 | Thera=12, 26 | None=-1 27 | } 28 | 29 | public static class EveSystemTypeExtensions 30 | { 31 | public static string ToDescriptionString(this EveSystemType This) 32 | { 33 | Type type = This.GetType(); 34 | 35 | string? name = Enum.GetName(type, This); 36 | if (name == null) 37 | return string.Empty; 38 | else 39 | { 40 | var members=type.GetMembers(); 41 | MemberInfo? member = members.Where(w => w.Name == name).FirstOrDefault(); 42 | 43 | DescriptionAttribute? attribute = ((member != null) ? member.GetCustomAttributes(true).Where(w => w.GetType() == typeof(DescriptionAttribute)).FirstOrDefault() as DescriptionAttribute : null); 44 | 45 | return ((attribute != null) ? attribute.Description : name); 46 | } 47 | } 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/Models/ClientUIDTest.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO; 2 | using Xunit; 3 | 4 | namespace WHMapper.Tests.Models.DTO; 5 | 6 | public class ClientUIDTest 7 | { 8 | [Fact] 9 | public void ClientUID_ShouldInitializeWithDefaultValues() 10 | { 11 | // Arrange & Act 12 | var clientUID = new ClientUID(); 13 | 14 | // Assert 15 | Assert.NotNull(clientUID.ClientId); 16 | Assert.Equal(string.Empty, clientUID.ClientId); 17 | } 18 | 19 | [Fact] 20 | public void ClientUID_ShouldAllowSettingAndGettingClientId() 21 | { 22 | // Arrange 23 | var clientUID = new ClientUID(); 24 | var testClientId = "TestClient123"; 25 | 26 | // Act 27 | clientUID.ClientId = testClientId; 28 | 29 | // Assert 30 | Assert.Equal(testClientId, clientUID.ClientId); 31 | } 32 | 33 | [Fact] 34 | public void ClientUID_ShouldHandleNullClientId() 35 | { 36 | // Arrange 37 | var clientUID = new ClientUID(); 38 | 39 | // Act 40 | clientUID.ClientId = null; 41 | 42 | // Assert 43 | Assert.Null(clientUID.ClientId); 44 | } 45 | 46 | [Fact] 47 | public void ClientUID_ShouldHandleEmptyClientId() 48 | { 49 | // Arrange 50 | var clientUID = new ClientUID(); 51 | 52 | // Act 53 | clientUID.ClientId = string.Empty; 54 | 55 | // Assert 56 | Assert.Equal(string.Empty, clientUID.ClientId); 57 | } 58 | } -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Users/Overview.razor: -------------------------------------------------------------------------------- 1 | @foreach(var account in Accounts) 2 | { 3 | var badgeColor = account.Tracking ? Color.Success : Color.Error; 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | @if(account.IsPrimary) 13 | { 14 | Primary 15 | } 16 | else 17 | { 18 | Set as Primary 19 | } 20 | @if(account.Tracking) 21 | { 22 | UnTrack 23 | } 24 | else 25 | { 26 | Track 27 | } 28 | 29 | 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Corporation/Corporation.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Corporation 4 | { 5 | public class Corporation 6 | { 7 | [JsonPropertyName("alliance_id")] 8 | public int AllianceId { get; set; } 9 | 10 | [JsonPropertyName("ceo_id")] 11 | public int CeoId { get; set; } 12 | 13 | [JsonPropertyName("creator_id")] 14 | public int CreatorId { get; set; } 15 | 16 | [JsonPropertyName("date_founded")] 17 | public DateTime DateFounded { get; set; } 18 | 19 | [JsonPropertyName("description")] 20 | public string Description { get; set; } = string.Empty; 21 | 22 | [JsonPropertyName("faction_id")] 23 | public int FactionId { get; set; } 24 | 25 | [JsonPropertyName("home_station_id")] 26 | public int HomeStationId { get; set; } 27 | 28 | [JsonPropertyName("member_count")] 29 | public int MemberCount { get; set; } 30 | 31 | [JsonPropertyName("name")] 32 | public string Name { get; set; } = string.Empty; 33 | 34 | [JsonPropertyName("shares")] 35 | public long Shares { get; set; } 36 | 37 | [JsonPropertyName("tax_rate")] 38 | public decimal TaxRate { get; set; } 39 | 40 | [JsonPropertyName("ticker")] 41 | public string Ticker { get; set; } = string.Empty; 42 | 43 | [JsonPropertyName("url")] 44 | public string Url { get; set; } = string.Empty; 45 | 46 | [JsonPropertyName("war_eligible")] 47 | public bool WarEligible { get; set; } 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20231003084350_AddWHNote.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; 3 | 4 | #nullable disable 5 | 6 | namespace WHMapper.Migrations 7 | { 8 | /// 9 | public partial class AddWHNote : Migration 10 | { 11 | /// 12 | protected override void Up(MigrationBuilder migrationBuilder) 13 | { 14 | migrationBuilder.CreateTable( 15 | name: "Notes", 16 | columns: table => new 17 | { 18 | Id = table.Column(type: "integer", nullable: false) 19 | .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), 20 | SoloarSystemId = table.Column(type: "integer", nullable: false), 21 | Comment = table.Column(type: "character varying(255)", maxLength: 255, nullable: false) 22 | }, 23 | constraints: table => 24 | { 25 | table.PrimaryKey("PK_Notes", x => x.Id); 26 | }); 27 | 28 | migrationBuilder.CreateIndex( 29 | name: "IX_Notes_SoloarSystemId", 30 | table: "Notes", 31 | column: "SoloarSystemId", 32 | unique: true); 33 | } 34 | 35 | /// 36 | protected override void Down(MigrationBuilder migrationBuilder) 37 | { 38 | migrationBuilder.DropTable( 39 | name: "Notes"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20251215_ReplaceIsEOLWithEOLStatus.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace WHMapper.Migrations 6 | { 7 | /// 8 | public partial class ReplaceIsEOLWithEOLStatus : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | // PostgreSQL cannot automatically cast boolean to integer, 14 | // so we use raw SQL with explicit USING clause. 15 | // false (not EOL) -> 0 (Normal) 16 | // true (EOL) -> 1 (EOL4h) 17 | migrationBuilder.Sql( 18 | @"ALTER TABLE ""SystemLinks"" 19 | RENAME COLUMN ""IsEndOfLifeConnection"" TO ""EndOfLifeStatus""; 20 | 21 | ALTER TABLE ""SystemLinks"" 22 | ALTER COLUMN ""EndOfLifeStatus"" TYPE integer 23 | USING CASE WHEN ""EndOfLifeStatus""::boolean THEN 1 ELSE 0 END;"); 24 | } 25 | 26 | /// 27 | protected override void Down(MigrationBuilder migrationBuilder) 28 | { 29 | // Convert back: 0 (Normal) -> false, anything else -> true 30 | migrationBuilder.Sql( 31 | @"ALTER TABLE ""SystemLinks"" 32 | ALTER COLUMN ""EndOfLifeStatus"" TYPE boolean 33 | USING (""EndOfLifeStatus"" <> 0); 34 | 35 | ALTER TABLE ""SystemLinks"" 36 | RENAME COLUMN ""EndOfLifeStatus"" TO ""IsEndOfLifeConnection"";"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20231225204239_Route db for planner.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; 3 | 4 | #nullable disable 5 | 6 | namespace WHMapper.Migrations 7 | { 8 | /// 9 | public partial class Routedbforplanner : Migration 10 | { 11 | /// 12 | protected override void Up(MigrationBuilder migrationBuilder) 13 | { 14 | migrationBuilder.CreateTable( 15 | name: "Routes", 16 | columns: table => new 17 | { 18 | Id = table.Column(type: "integer", nullable: false) 19 | .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), 20 | EveEntityId = table.Column(type: "integer", nullable: true), 21 | SolarSystemId = table.Column(type: "integer", nullable: false) 22 | }, 23 | constraints: table => 24 | { 25 | table.PrimaryKey("PK_Routes", x => x.Id); 26 | }); 27 | 28 | migrationBuilder.CreateIndex( 29 | name: "IX_Routes_SolarSystemId_EveEntityId", 30 | table: "Routes", 31 | columns: new[] { "SolarSystemId", "EveEntityId" }, 32 | unique: true); 33 | } 34 | 35 | /// 36 | protected override void Down(MigrationBuilder migrationBuilder) 37 | { 38 | migrationBuilder.DropTable( 39 | name: "Routes"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /deploy/localhost/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | db: 3 | image: postgres:17-alpine 4 | restart: always 5 | environment: 6 | POSTGRES_USER: ${POSTGRES_USER:-postgres} 7 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secret} 8 | POSTGRES_DB: whmapper 9 | PGDATA: /data/postgres 10 | volumes: 11 | - postgres:/data/postgres 12 | networks: 13 | - net 14 | 15 | redis: 16 | image: redis:8-alpine 17 | restart: always 18 | networks: 19 | - net 20 | 21 | whmapper: 22 | image: ghcr.io/pfh59/eve-whmapper:latest 23 | restart: unless-stopped 24 | environment: 25 | - EveSSO__ClientId=xxxxxxxxx 26 | - EveSSO__Secret=xxxxxxxxx 27 | - ConnectionStrings__DatabaseConnection=server=db;port=5432;database=whmapper;User Id=postgres;Password=secret 28 | - ConnectionStrings__RedisConnection=redis:6379 29 | - Serilog__MinimumLevel__Default=Warning 30 | - Serilog__MinimumLevel__Override__Microsoft.EntityFrameworkCore.Database.Command=Warning 31 | - DisableSignalRCertificateValidation=true 32 | links: 33 | - db 34 | - redis 35 | depends_on: 36 | - db 37 | - redis 38 | networks: 39 | - net 40 | volumes: 41 | - ./Logs:/app/Logs 42 | 43 | nginx: 44 | image: nginx:alpine 45 | restart: unless-stopped 46 | ports: 47 | - "80:80" 48 | - "443:443" 49 | volumes: 50 | - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro 51 | - ./nginx/certs/:/etc/nginx/certs/:ro 52 | links: 53 | - whmapper 54 | depends_on: 55 | - whmapper 56 | networks: 57 | - net 58 | networks: 59 | net: 60 | 61 | volumes: 62 | postgres: 63 | -------------------------------------------------------------------------------- /src/WHMapper.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 25.0.1700.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WHMapper", "WHMapper\WHMapper.csproj", "{42856DAF-BBD6-4651-8BD9-D6D29C9692CB}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WHMapper.Tests", "WHMapper.Tests\WHMapper.Tests.csproj", "{0E3C0404-014F-4859-82B6-B5C90145277E}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {42856DAF-BBD6-4651-8BD9-D6D29C9692CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {42856DAF-BBD6-4651-8BD9-D6D29C9692CB}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {42856DAF-BBD6-4651-8BD9-D6D29C9692CB}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {42856DAF-BBD6-4651-8BD9-D6D29C9692CB}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {0E3C0404-014F-4859-82B6-B5C90145277E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {0E3C0404-014F-4859-82B6-B5C90145277E}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {0E3C0404-014F-4859-82B6-B5C90145277E}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {0E3C0404-014F-4859-82B6-B5C90145277E}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {7986683D-CC03-4CE9-9506-E4E5642D94B6} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/WHMapper/Components/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Eve WHMapper 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /deploy/docker/renew-certificates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | clear 4 | 5 | # Require script to be run via sudo, but not as root 6 | if [[ $EUID != 0 ]]; then 7 | echo "Script must be run with root privilages!" 8 | exit 1 9 | elif [[ $EUID = $UID && "$SUDO_USER" = "" ]]; then 10 | echo "Script must be run as current user via 'sudo', not as the root user!" 11 | exit 1 12 | fi 13 | 14 | set -e 15 | #clear screen 16 | clear 17 | 18 | echo "#------------------------------------------------------------#" 19 | 20 | echo "Rnewal certificates Wizard" 21 | echo "Configation Certbot and HAProxy" 22 | while true; do 23 | read -p "Enter your domain [Required]: " DOMAIN 24 | if [[ -z "$DOMAIN" ]]; then 25 | echo -e "\e[31mError: Domain must be set\e[0m" 26 | elif ! [[ "$DOMAIN" =~ ^[a-zA-Z0-9.-]+$ ]]; then 27 | echo -e "\e[31mError: Invalid domain format\e[0m" 28 | else 29 | break 30 | fi 31 | done 32 | 33 | # Merge private key and full chain in one file and add them to haproxy certs folder 34 | function cat-cert() { 35 | dir="./haproxy/certbot/conf/live/$DOMAIN" 36 | cat "$dir/privkey.pem" "$dir/fullchain.pem" > "./haproxy/certs/$DOMAIN.pem" 37 | } 38 | 39 | echo "Simulate the certificate renewal for the requested domain name" 40 | docker-compose -f ./haproxy/docker-compose.yml run --rm certbot renew --dry-run 41 | 42 | #check if test if ok 43 | if [ $? -ne 0 ]; then 44 | echo -e "\e[31mError: Certificate renewal failed\e[0m" 45 | exit 1 46 | fi 47 | 48 | echo "Renew the certificate for the requested domain name" 49 | docker-compose -f ./haproxy/docker-compose.yml run --rm certbot renew 50 | 51 | #check if renew is ok 52 | if [ $? -ne 0 ]; then 53 | echo -e "\e[31mError: Certificate renewal failed\e[0m" 54 | exit 1 55 | fi 56 | 57 | echo "Run merge certificate for the requested domain name" 58 | cat-cert $DOMAIN 59 | 60 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveAPI/Universe/ESISolarSystem.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace WHMapper.Models.DTO.EveAPI.Universe 4 | { 5 | public class ESISolarSystem 6 | { 7 | 8 | [JsonPropertyName("star_id")] 9 | public int StarId { get; private set; } 10 | 11 | [JsonPropertyName("system_id")] 12 | public int SystemId { get; private set; } 13 | 14 | [JsonPropertyName("name")] 15 | public string Name { get; private set; } 16 | 17 | [JsonPropertyName("position")] 18 | public Position Position { get; private set; } 19 | 20 | [JsonPropertyName("security_status")] 21 | public float SecurityStatus { get; private set; } 22 | 23 | [JsonPropertyName("security_class")] 24 | public string SecurityClass { get; private set; } 25 | 26 | [JsonPropertyName("constellation_id")] 27 | public int ConstellationId { get; private set; } 28 | 29 | 30 | //[JsonPropertyName("planets")] 31 | //public ICollection Planets { get; private set; } = new List(); 32 | 33 | 34 | [JsonPropertyName("stargates")] 35 | public int[] Stargates { get; private set; } 36 | 37 | 38 | [JsonPropertyName("stations")] 39 | public int[] Stations { get; private set; } 40 | 41 | public ESISolarSystem(int starId, int systemId, string name, Position position, float securityStatus, string securityClass, int constellationId/*, ICollection planets*/ ,int[] stargates, int[] stations) 42 | => (StarId, SystemId, Name, Position, SecurityStatus, SecurityClass, ConstellationId/*, Planets*/,Stargates, Stations) = (starId, systemId, name, position, securityStatus, securityClass, constellationId/*, planets*/,stargates, stations); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/RoutePlanner/Delete.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Components; 3 | using MudBlazor; 4 | 5 | namespace WHMapper.Components.Pages.Mapper.RoutePlanner; 6 | 7 | 8 | [Authorize(Policy = "Access")] 9 | public partial class Delete 10 | { 11 | private const string MSG_DELETE_ROUTE = "Do you want to delete this route?"; 12 | private const string MSG_ROUTE_DEL_SUCCESS = "Route successfully deleted"; 13 | private const string MSG_ROUTE_DEL_FAIL = "Route not deleted"; 14 | 15 | [Inject] 16 | private IEveMapperRoutePlannerHelper EveMapperRoutePlannerHelper { get; set; } = null!; 17 | 18 | [Inject] 19 | private ISnackbar Snackbar { get; set; } = null!; 20 | 21 | [Inject] 22 | public ILogger Logger { get; set; } = null!; 23 | 24 | [CascadingParameter] 25 | IMudDialogInstance MudDialog { get; set; } = null!; 26 | 27 | 28 | [Parameter] 29 | public int RouteId { get; set; } 30 | 31 | 32 | private void Cancel() 33 | { 34 | MudDialog?.Cancel(); 35 | } 36 | 37 | private async Task Submit() 38 | { 39 | if (RouteId > 0) 40 | await DeleteRoute(); 41 | } 42 | 43 | private async Task DeleteRoute() 44 | { 45 | if (RouteId > 0) 46 | { 47 | var result = await EveMapperRoutePlannerHelper.DeleteRoute(RouteId); 48 | if (result) 49 | { 50 | Snackbar.Add(MSG_ROUTE_DEL_SUCCESS, Severity.Success); 51 | MudDialog?.Close(DialogResult.Ok(true)); 52 | } 53 | else 54 | { 55 | Snackbar.Add(MSG_ROUTE_DEL_FAIL, Severity.Error); 56 | MudDialog?.Close(DialogResult.Ok(false)); 57 | } 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/WHMapper/Hubs/ConnectionMapping.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Hubs; 2 | 3 | public class ConnectionMapping where T : notnull 4 | { 5 | private readonly Dictionary> _connections = new Dictionary>(); 6 | 7 | public int Count 8 | { 9 | get 10 | { 11 | return _connections.Count; 12 | } 13 | } 14 | 15 | public void Add(T key, string connectionId) 16 | { 17 | lock (_connections) 18 | { 19 | HashSet? connections=null; 20 | if (!_connections.TryGetValue(key, out connections)) 21 | { 22 | connections = new HashSet(); 23 | _connections.Add(key, connections); 24 | } 25 | 26 | lock (connections) 27 | { 28 | connections.Add(connectionId); 29 | } 30 | } 31 | } 32 | 33 | public IEnumerable GetConnections(T key) 34 | { 35 | HashSet? connections=null; 36 | if (_connections.TryGetValue(key, out connections)) 37 | { 38 | return connections; 39 | } 40 | 41 | return Enumerable.Empty(); 42 | } 43 | 44 | public void Remove(T key, string connectionId) 45 | { 46 | lock (_connections) 47 | { 48 | HashSet? connections=null; 49 | if (!_connections.TryGetValue(key, out connections)) 50 | { 51 | return; 52 | } 53 | 54 | lock (connections) 55 | { 56 | connections.Remove(connectionId); 57 | 58 | if (connections.Count == 0) 59 | { 60 | _connections.Remove(key); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/EveOnlineAccessTokenHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http.Headers; 2 | using System.Security.Claims; 3 | using WHMapper.Services.EveOAuthProvider.Services; 4 | 5 | namespace WHMapper.Services.EveAPI 6 | { 7 | public class EveOnlineAccessTokenHandler : DelegatingHandler 8 | { 9 | private readonly IEveOnlineTokenProvider _eveAPITokenProvider; 10 | private readonly IHttpContextAccessor _contextAccessor; 11 | 12 | public EveOnlineAccessTokenHandler(IEveOnlineTokenProvider eveAPITokenProvider, IHttpContextAccessor contextAccessor) 13 | { 14 | _eveAPITokenProvider = eveAPITokenProvider ?? throw new ArgumentNullException(nameof(eveAPITokenProvider)); 15 | _contextAccessor = contextAccessor ?? throw new ArgumentNullException(nameof(contextAccessor)); 16 | } 17 | 18 | protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 19 | { 20 | 21 | var user = _contextAccessor?.HttpContext?.User as ClaimsPrincipal; 22 | 23 | 24 | var userId = user?.FindFirst(ClaimTypes.NameIdentifier)?.Value; 25 | if (string.IsNullOrEmpty(userId)) 26 | { 27 | throw new UnauthorizedAccessException("User ID is not found."); 28 | } 29 | 30 | if (await _eveAPITokenProvider.IsTokenExpire(userId)) 31 | { 32 | await _eveAPITokenProvider.RefreshAccessToken(userId); 33 | } 34 | 35 | var token = (await _eveAPITokenProvider.GetToken(userId))?.AccessToken; 36 | if (!string.IsNullOrEmpty(token)) 37 | { 38 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 39 | } 40 | 41 | return await base.SendAsync(request, cancellationToken); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/EVEOnlineAuthenticationDefaults.cs: -------------------------------------------------------------------------------- 1 | namespace WHMapper.Services.EveOAuthProvider 2 | { 3 | public static class EVEOnlineAuthenticationDefaults 4 | { 5 | /// 6 | /// Default value for . 7 | /// 8 | public const string AuthenticationScheme = "EVEOnline"; 9 | 10 | /// 11 | /// Default value for . 12 | /// 13 | public static readonly string DisplayName = "EVEOnline"; 14 | 15 | /// 16 | /// Default value for . 17 | /// 18 | public static readonly string Issuer = "EVEOnline"; 19 | 20 | /// 21 | /// Default value for . 22 | /// 23 | public static readonly string CallbackPath = "/signin-eveonline"; 24 | 25 | /// 26 | /// Default value for . 27 | /// 28 | public static readonly string AuthorizationEndpoint = "https://login.eveonline.com/v2/oauth/authorize"; 29 | 30 | /// 31 | /// Default value for . 32 | /// 33 | public static readonly string TokenEndpoint = "https://login.eveonline.com/v2/oauth/token"; 34 | public static readonly string JWKEndpoint = "https://login.eveonline.com/oauth/jwks"; 35 | public static readonly string RevokeTokenEndpoint = "https://login.eveonline.com/v2/oauth/revoke"; 36 | 37 | public const string Scopes = "urn:eveonline:scopes"; 38 | 39 | public static readonly string ValideIssuer = "https://login.eveonline.com"; 40 | public static readonly string ValideAudience = "EVE Online"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/AuthorizationPolicies/EveMapperMapHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using System.Security.Claims; 3 | 4 | namespace WHMapper.Services.EveMapper.AuthorizationPolicies; 5 | 6 | public class EveMapperMapHandler: AuthorizationHandler 7 | { 8 | 9 | private readonly IEveMapperAccessHelper _eveMapperAccessHelper; 10 | 11 | public EveMapperMapHandler(IEveMapperAccessHelper eveMapperAccessHelper) 12 | { 13 | _eveMapperAccessHelper = eveMapperAccessHelper; 14 | } 15 | 16 | protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, EveMapperMapRequirement requirement) 17 | { 18 | var characterId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; 19 | 20 | if (string.IsNullOrEmpty(characterId)) 21 | return; 22 | 23 | var pendingRequirements = context.PendingRequirements.ToList(); 24 | if (pendingRequirements.Count > 0) 25 | { 26 | foreach (var pendingRequirement in pendingRequirements) 27 | { 28 | if (pendingRequirement is EveMapperMapRequirement) 29 | { 30 | // get mapId from resource, passed in from blazor 31 | // page component 32 | var resource = context.Resource?.ToString(); 33 | var hasParsed = int.TryParse(resource, out int mapId); 34 | 35 | if (hasParsed) 36 | { 37 | // check if user has access to map 38 | if (await _eveMapperAccessHelper.IsEveMapperMapAccessAuthorized(Convert.ToInt32(characterId),mapId)) 39 | context.Succeed(requirement); 40 | } 41 | } 42 | } 43 | } 44 | 45 | 46 | 47 | return; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/WHMapper.Tests/Models/MapAdminTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using WHMapper.Models.Db; 3 | using WHMapper.Models.DTO.MapAdmin; 4 | using Xunit; 5 | 6 | 7 | namespace WHMapper.Tests.Models; 8 | 9 | 10 | public class MapAdminTests 11 | { 12 | [Fact] 13 | public void Constructor_ShouldInitializeProperties() 14 | { 15 | // Arrange 16 | var whMap = new WHMap("Test Map"); 17 | whMap.Id = 1; 18 | whMap.WHAccesses.Add(new WHAccess(1,"Test Access")); 19 | 20 | // Act 21 | var mapAdmin = new MapAdmin(whMap); 22 | 23 | // Assert 24 | Assert.Equal(1, mapAdmin.Id); 25 | Assert.Equal("Test Map", mapAdmin.Name); 26 | Assert.NotNull(mapAdmin.WHMapAccesses); 27 | Assert.Single(mapAdmin.WHMapAccesses); 28 | Assert.False(mapAdmin.ShowAccessDetails); 29 | } 30 | 31 | [Fact] 32 | public void Constructor_ShouldHandleNullWHMap() 33 | { 34 | // Act 35 | var mapAdmin = new MapAdmin(null); 36 | 37 | // Assert 38 | Assert.Equal(-1, mapAdmin.Id); 39 | Assert.Equal(string.Empty, mapAdmin.Name); 40 | Assert.Null(mapAdmin.WHMapAccesses); 41 | Assert.False(mapAdmin.ShowAccessDetails); 42 | } 43 | 44 | [Fact] 45 | public void ShowAccessDetails_ShouldBeFalseByDefault() 46 | { 47 | // Arrange 48 | var whMap = new WHMap("Test Map"); 49 | 50 | // Act 51 | var mapAdmin = new MapAdmin(whMap); 52 | 53 | // Assert 54 | Assert.False(mapAdmin.ShowAccessDetails); 55 | } 56 | 57 | [Fact] 58 | public void ShowAccessDetails_ShouldBeSettable() 59 | { 60 | // Arrange 61 | var whMap = new WHMap("Test Map"); 62 | var mapAdmin = new MapAdmin(whMap); 63 | 64 | // Act 65 | mapAdmin.ShowAccessDetails = true; 66 | 67 | // Assert 68 | Assert.True(mapAdmin.ShowAccessDetails); 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20240828145305_Allow_Multi_Map.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace WHMapper.Migrations 6 | { 7 | /// 8 | public partial class Allow_Multi_Map : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.CreateTable( 14 | name: "WHAccessWHMap", 15 | columns: table => new 16 | { 17 | WHAccessesId = table.Column(type: "integer", nullable: false), 18 | WHMapId = table.Column(type: "integer", nullable: false) 19 | }, 20 | constraints: table => 21 | { 22 | table.PrimaryKey("PK_WHAccessWHMap", x => new { x.WHAccessesId, x.WHMapId }); 23 | table.ForeignKey( 24 | name: "FK_WHAccessWHMap_Accesses_WHAccessesId", 25 | column: x => x.WHAccessesId, 26 | principalTable: "Accesses", 27 | principalColumn: "Id", 28 | onDelete: ReferentialAction.Cascade); 29 | table.ForeignKey( 30 | name: "FK_WHAccessWHMap_Maps_WHMapId", 31 | column: x => x.WHMapId, 32 | principalTable: "Maps", 33 | principalColumn: "Id", 34 | onDelete: ReferentialAction.Cascade); 35 | }); 36 | 37 | migrationBuilder.CreateIndex( 38 | name: "IX_WHAccessWHMap_WHMapId", 39 | table: "WHAccessWHMap", 40 | column: "WHMapId"); 41 | } 42 | 43 | /// 44 | protected override void Down(MigrationBuilder migrationBuilder) 45 | { 46 | migrationBuilder.DropTable( 47 | name: "WHAccessWHMap"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Overview.razor: -------------------------------------------------------------------------------- 1 | @page "/whmapper" 2 | 3 | @using Blazor.Diagrams.Core; 4 | @using Blazor.Diagrams.Core.Geometry; 5 | @using Blazor.Diagrams.Core.Models; 6 | @using Blazor.Diagrams.Components; 7 | @using Blazor.Diagrams.Algorithms; 8 | @using WHMapper.Models.Db.Enums; 9 | 10 | 11 | 12 | 43 | 44 | @if (_loading) 45 | { 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /deploy/localhost/docker/README.MD: -------------------------------------------------------------------------------- 1 | # Eve WHMapper Local Deployment 2 | 3 | This guide explains how to deploy Eve WHMapper locally using Docker and Nginx. 4 | 5 | ## Prerequisites 6 | 7 | - **Docker** and **Docker Compose** installed 8 | - **mkcert** installed for generating local SSL certificates 9 | - **PowerShell** (Windows) or compatible shell 10 | - **You must add `whmapper.local` to your `C:\Windows\System32\drivers\etc\hosts` file with your private IP address** 11 | Example: 12 | ``` 13 | 192.168.x.x whmapper.local 14 | ``` 15 | Replace `192.168.x.x` with your actual private IP. 16 | 17 | ## Deployment Steps 18 | 19 | ### 1. Clone the Repository 20 | 21 | ```sh 22 | git clone https://github.com/your-org/eve-whmapper.git 23 | cd eve-whmapper/deploy/localhost/docker 24 | ``` 25 | 26 | ### 2. Initialize the Environment 27 | 28 | This script will: 29 | - Remove previous containers and volumes 30 | - Generate a self-signed SSL certificate for `whmapper.local` 31 | - Prompt for database and EVE SSO credentials 32 | - Prepare configuration files 33 | 34 | **Windows:** 35 | ```powershell 36 | .\init.ps1 37 | ``` 38 | 39 | **macOS/Linux:** 40 | ```sh 41 | pwsh ./init.ps1 42 | ``` 43 | 44 | ### 3. Start the Containers 45 | 46 | ```powershell 47 | .\start.ps1 48 | ``` 49 | or 50 | ```sh 51 | pwsh ./start.ps1 52 | ``` 53 | 54 | ### 4. Access the Application 55 | 56 | Open your browser and go to: 57 | 58 | ``` 59 | https://whmapper.local 60 | ``` 61 | 62 | > You may need to trust the generated certificate in your browser. 63 | 64 | ### 5. Stop the Containers 65 | 66 | ```powershell 67 | .\stop.ps1 68 | ``` 69 | or 70 | ```sh 71 | pwsh ./stop.ps1 72 | ``` 73 | 74 | ## Troubleshooting 75 | 76 | - Ensure required files exist: 77 | - `nginx/conf/nginx.conf` 78 | - `nginx/certs/whmapper.local.pem` 79 | - `nginx/certs/whmapper.local.key` 80 | - `docker-compose.yml` 81 | - If you see SSL errors, make sure your browser trusts the local CA installed by `mkcert`. 82 | - Make sure `whmapper.local` is mapped to your private IP in your hosts file. 83 | 84 | --- -------------------------------------------------------------------------------- /src/WHMapper/Repositories/ADefaultRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace WHMapper.Repositories 4 | { 5 | 6 | /// 7 | /// 8 | /// 9 | /// Server DbContext 10 | /// Object to Manage in database 11 | /// type of Id of Object 12 | public abstract class ADefaultRepository where C : DbContext 13 | { 14 | protected readonly ILogger _logger; 15 | protected readonly IDbContextFactory _contextFactory; 16 | 17 | protected abstract Task?> AGetAll(); 18 | protected abstract Task AGetById(U id); 19 | protected abstract Task ACreate(T item); 20 | protected abstract Task AUpdate(U id, T item); 21 | protected abstract Task ADeleteById(U id); 22 | protected abstract Task AGetCountAsync(); 23 | 24 | protected ADefaultRepository(ILogger logger,IDbContextFactory dbContext) 25 | { 26 | _logger = logger; 27 | _contextFactory = dbContext; 28 | 29 | } 30 | 31 | public async Task Create(T item) 32 | { 33 | 34 | return await ACreate(item); 35 | } 36 | 37 | public async Task DeleteById(U id) 38 | { 39 | return await ADeleteById(id); 40 | } 41 | 42 | public async Task?> GetAll() 43 | { 44 | return await AGetAll(); 45 | } 46 | 47 | public async Task GetById(U id) 48 | { 49 | return await AGetById(id); 50 | } 51 | 52 | public async Task Update(U id, T item) 53 | { 54 | return await AUpdate(id, item); 55 | } 56 | 57 | public async Task GetCountAsync() 58 | { 59 | return await AGetCountAsync(); 60 | } 61 | 62 | 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/WHMapper/Hubs/IWHMapperNotificationHub.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.Db.Enums; 2 | 3 | namespace WHMapper.Hubs 4 | { 5 | public interface IWHMapperNotificationHub 6 | { 7 | Task NotifyUserConnected(int accountID); 8 | Task NotifyUserDisconnected(int accountID); 9 | Task NotifyUserPosition(int accountID,int mapId,int wormholeId); 10 | Task NotifyWormoleAdded(int accountID, int mapId,int wormholeId); 11 | Task NotifyWormholeRemoved(int accountID, int mapId,int wormholeId); 12 | Task NotifyLinkAdded(int accountID, int mapId, int linkId); 13 | Task NotifyLinkRemoved(int accountID, int mapId, int linkId); 14 | Task NotifyWormoleMoved(int accountID, int mapId, int wormholeId,double posx,double posy); 15 | Task NotifyLinkChanged(int accountID,int mapId, int linkId, int eolStatus, SystemLinkSize size, int mass); 16 | Task NotifyWormholeNameExtensionChanged(int accountID, int mapId, int wormholeId,char? extension); 17 | Task NotifyWormholeSignaturesChanged(int accountID, int mapId, int wormholeId); 18 | Task NotifyWormholeLockChanged(int accountID, int mapId, int wormholeId, bool locked); 19 | Task NotifyWormholeSystemStatusChanged(int accountID, int mapId, int wormholeId, WHSystemStatus systemStatus); 20 | Task NotifyWormholeAlternateNameChanged(int accountID, int mapId, int wormholeId, string? alternateName); 21 | Task NotifyMapAdded(int accountID, int mapId); 22 | Task NotifyMapRemoved(int accountID, int mapId); 23 | Task NotifyMapNameChanged(int accountID, int mapId, string newName); 24 | Task NotifyAllMapsRemoved(int accountID); 25 | Task NotifyMapAccessesAdded(int accountID, int mapId, IEnumerable accessId); 26 | Task NotifyMapAccessRemoved(int accountID, int mapId, int accessId); 27 | Task NotifyMapAllAccessesRemoved(int accountID, int mapId); 28 | Task NotifyUserOnMapConnected(int accountID, int mapId); 29 | Task NotifyUserOnMapDisconnected(int accountID, int mapId); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /deploy/kubernetes/deploys/backend.yaml: -------------------------------------------------------------------------------- 1 | ################################## 2 | ### POSTGRES 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: postgres 7 | namespace: evemapper 8 | labels: 9 | order: "6" 10 | spec: 11 | replicas: 1 12 | selector: 13 | matchLabels: 14 | component: postgres 15 | template: 16 | metadata: 17 | labels: 18 | component: postgres 19 | spec: 20 | containers: 21 | - name: postgres 22 | image: bitnami/postgresql:latest 23 | ports: 24 | - containerPort: 5432 25 | envFrom: 26 | - configMapRef: 27 | name: evemapper-config-map 28 | - secretRef: 29 | name: evemapper-secrets 30 | --- 31 | 32 | apiVersion: v1 33 | kind: Service 34 | metadata: 35 | name: postgres-cluster-ip-service 36 | namespace: evemapper 37 | labels: 38 | order: "7" 39 | spec: 40 | type: NodePort 41 | selector: 42 | component: postgres 43 | ports: 44 | - port: 5432 45 | targetPort: 5432 46 | nodePort: 31252 47 | --- 48 | 49 | ################################## 50 | ### REDIS 51 | apiVersion: apps/v1 52 | kind: Deployment 53 | metadata: 54 | name: redis 55 | namespace: evemapper 56 | labels: 57 | order: "8" 58 | spec: 59 | replicas: 1 60 | selector: 61 | matchLabels: 62 | component: redis 63 | template: 64 | metadata: 65 | labels: 66 | component: redis 67 | spec: 68 | containers: 69 | - name: redis 70 | image: redis:latest 71 | ports: 72 | - containerPort: 6379 73 | envFrom: 74 | - configMapRef: 75 | name: evemapper-config-map 76 | - secretRef: 77 | name: evemapper-secrets 78 | --- 79 | 80 | apiVersion: v1 81 | kind: Service 82 | metadata: 83 | name: redis-cluster-ip-service 84 | namespace: evemapper 85 | labels: 86 | order: "9" 87 | spec: 88 | type: NodePort 89 | selector: 90 | component: redis 91 | ports: 92 | - port: 6379 93 | targetPort: 6379 94 | nodePort: 31253 95 | --- 96 | 97 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20240909201955_Update_Notes_To_Be_Unique_For_Multi_Map.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace WHMapper.Migrations 6 | { 7 | /// 8 | public partial class Update_Notes_To_Be_Unique_For_Multi_Map : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.DropIndex( 14 | name: "IX_Notes_SoloarSystemId", 15 | table: "Notes"); 16 | 17 | migrationBuilder.AddColumn( 18 | name: "MapId", 19 | table: "Notes", 20 | type: "integer", 21 | nullable: false, 22 | defaultValue: 1); 23 | 24 | migrationBuilder.CreateIndex( 25 | name: "IX_Notes_MapId_SoloarSystemId", 26 | table: "Notes", 27 | columns: new[] { "MapId", "SoloarSystemId" }, 28 | unique: true); 29 | 30 | migrationBuilder.AddForeignKey( 31 | name: "FK_Notes_Maps_MapId", 32 | table: "Notes", 33 | column: "MapId", 34 | principalTable: "Maps", 35 | principalColumn: "Id", 36 | onDelete: ReferentialAction.Cascade); 37 | } 38 | 39 | /// 40 | protected override void Down(MigrationBuilder migrationBuilder) 41 | { 42 | migrationBuilder.DropForeignKey( 43 | name: "FK_Notes_Maps_MapId", 44 | table: "Notes"); 45 | 46 | migrationBuilder.DropIndex( 47 | name: "IX_Notes_MapId_SoloarSystemId", 48 | table: "Notes"); 49 | 50 | migrationBuilder.DropColumn( 51 | name: "MapId", 52 | table: "Notes"); 53 | 54 | migrationBuilder.CreateIndex( 55 | name: "IX_Notes_SoloarSystemId", 56 | table: "Notes", 57 | column: "SoloarSystemId", 58 | unique: true); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Administration/Map/Add.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Components; 3 | using MudBlazor; 4 | using WHMapper.Models.Db; 5 | using WHMapper.Repositories.WHMaps; 6 | 7 | namespace WHMapper.Components.Pages.Mapper.Administration.Map; 8 | 9 | [Authorize(Policy = "Admin")] 10 | public partial class Add 11 | { 12 | private MudForm _form = null!; 13 | private bool _success = false; 14 | 15 | private string _mapName = null!; 16 | 17 | [Inject] 18 | private ILogger Logger { get; set; } = null!; 19 | 20 | [Inject] 21 | private ISnackbar Snackbar { get; set; } = null!; 22 | 23 | [Inject] 24 | private IWHMapRepository DbMap {get;set;}=null!; 25 | 26 | [CascadingParameter] 27 | IMudDialogInstance MudDialog { get; set; } = null!; 28 | 29 | 30 | 31 | private async Task Submit() 32 | { 33 | await _form.Validate(); 34 | 35 | if (_form.IsValid) 36 | { 37 | // Check if map name already exists 38 | var existingMap = await DbMap.GetByNameAsync(_mapName); 39 | if (existingMap != null) 40 | { 41 | Snackbar.Add("Map name already exists. Please choose a different name.", Severity.Warning); 42 | return; 43 | } 44 | 45 | WHMap newMap = new WHMap(_mapName); 46 | if(await DbMap.Create(newMap) == null) 47 | { 48 | Snackbar.Add("Error while creating map", Severity.Error); 49 | MudDialog.Close(DialogResult.Cancel); 50 | } 51 | else 52 | { 53 | MudDialog.Close(DialogResult.Ok(newMap)); 54 | } 55 | } 56 | else 57 | { 58 | Logger.LogError("Error while validating form"); 59 | Snackbar?.Add("Error while validating form", Severity.Error); 60 | MudDialog.Close(DialogResult.Cancel); 61 | } 62 | } 63 | 64 | 65 | private void Cancel() 66 | { 67 | MudDialog.Cancel(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Pages/Mapper/Signatures/Import.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Name 20 | Group 21 | Type 22 | 23 | 24 | @context.Name 25 | @context.Group 26 | @context.Type 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Cancel 36 | Update Signatures 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/WHMapper/Migrations/20240912202232_Update_Route_To_Be_Unique_For_Multi_Map.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace WHMapper.Migrations 6 | { 7 | /// 8 | public partial class Update_Route_To_Be_Unique_For_Multi_Map : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.DropIndex( 14 | name: "IX_Routes_SolarSystemId_EveEntityId", 15 | table: "Routes"); 16 | 17 | migrationBuilder.AddColumn( 18 | name: "MapId", 19 | table: "Routes", 20 | type: "integer", 21 | nullable: false, 22 | defaultValue: 1); 23 | 24 | migrationBuilder.CreateIndex( 25 | name: "IX_Routes_MapId_SolarSystemId_EveEntityId", 26 | table: "Routes", 27 | columns: new[] { "MapId", "SolarSystemId", "EveEntityId" }, 28 | unique: true); 29 | 30 | migrationBuilder.AddForeignKey( 31 | name: "FK_Routes_Maps_MapId", 32 | table: "Routes", 33 | column: "MapId", 34 | principalTable: "Maps", 35 | principalColumn: "Id", 36 | onDelete: ReferentialAction.Cascade); 37 | } 38 | 39 | /// 40 | protected override void Down(MigrationBuilder migrationBuilder) 41 | { 42 | migrationBuilder.DropForeignKey( 43 | name: "FK_Routes_Maps_MapId", 44 | table: "Routes"); 45 | 46 | migrationBuilder.DropIndex( 47 | name: "IX_Routes_MapId_SolarSystemId_EveEntityId", 48 | table: "Routes"); 49 | 50 | migrationBuilder.DropColumn( 51 | name: "MapId", 52 | table: "Routes"); 53 | 54 | migrationBuilder.CreateIndex( 55 | name: "IX_Routes_SolarSystemId_EveEntityId", 56 | table: "Routes", 57 | columns: new[] { "SolarSystemId", "EveEntityId" }, 58 | unique: true); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/WHMapper/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "http_port": 80, 3 | "https_port": 443, 4 | "Serilog": { 5 | "MinimumLevel": { 6 | "Default": "Warning", 7 | "Override": { 8 | "Microsoft": "Warning", 9 | "Microsoft.Hosting.Lifetime": "Information", 10 | "Microsoft.EntityFrameworkCore.Database.Command": "Warning", 11 | "Microsoft.AspNetCore.DataProtection": "Warning" 12 | } 13 | }, 14 | "WriteTo": [ 15 | { 16 | "Name": "File", 17 | "Args": { 18 | "path": "Logs/whmapper-.log", 19 | "rollingInterval": "Day", 20 | "retainedFileCountLimit": 7, 21 | "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" 22 | } 23 | }, 24 | { 25 | "Name": "Console", 26 | "Args": { 27 | "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" 28 | } 29 | } 30 | ] 31 | }, 32 | "AllowedHosts": "*", 33 | "DisableSignalRCertificateValidation": false, 34 | "EveSSO": { 35 | "Domain": "login.eveonline.com", 36 | "ClientId": "", 37 | "Secret": "", 38 | "DefaultScopes": [ 39 | "esi-location.read_location.v1", 40 | "esi-location.read_ship_type.v1", 41 | "esi-ui.open_window.v1", 42 | "esi-ui.write_waypoint.v1", 43 | "esi-search.search_structures.v1" 44 | ] 45 | }, 46 | "EveAPI": { 47 | "Domain": "esi.evetech.net" 48 | }, 49 | "ConnectionStrings": { 50 | "DatabaseConnection": "server=localhost;port=5432;database=whmapper;User Id=postgres;Password=secret", 51 | "RedisConnection": "localhost:6379" 52 | }, 53 | "AnoikDataSupplier": { 54 | "JsonFilePath": "./Resources/Anoik/static.json" 55 | }, 56 | "SdeDataSupplier": { 57 | "BaseUrl": "https://eve-static-data-export.s3-eu-west-1.amazonaws.com/tranquility/" 58 | }, 59 | "Otlp": { 60 | "Enabled": true, 61 | "EnableSystemInstrumentation": false, 62 | "Endpoint": "https://telemetry.whmapper.ovh:54317", 63 | "MetricsExportIntervalMilliseconds": 10000, 64 | "MetricsExportTimeoutMilliseconds": 10000 65 | }, 66 | "WHMapperStoreMeterName": "WHMMapper.Meter" 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveMapper/IEveMapperRoutePlannerHelper.cs: -------------------------------------------------------------------------------- 1 | using WHMapper.Models.DTO.EveAPI.Route.Enums; 2 | using WHMapper.Models.DTO.RoutePlanner; 3 | 4 | namespace WHMapper 5 | { 6 | public interface IEveMapperRoutePlannerHelper 7 | { 8 | /// 9 | /// Get all routes from a solar system 10 | /// mapperConnections is the array of all mapper connection between two Wormhole. 11 | /// 12 | /// 13 | /// 14 | /// 15 | Task?> GetRoutesForAll(int mapId,int fromSolarSystemId, RouteType routeType, IEnumerable? extraConnections); 16 | 17 | /// 18 | /// Get my favorites routes from selected system 19 | /// 20 | /// 21 | /// 22 | /// 23 | Task?> GetMyRoutes(int mapId,int fromSolarSystemId, RouteType routeType, IEnumerable? extraConnections); 24 | 25 | 26 | /// 27 | /// Get Thera routes from selected system 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | Task?> GetTheraRoutes(int fromSolarSystemId, RouteType routeType, IEnumerable? extraConnections); 34 | 35 | /// 36 | /// Get Turnur routes from selected system 37 | /// 38 | /// 39 | /// 40 | /// 41 | /// 42 | Task?> GetTurnurRoutes(int fromSolarSystemId, RouteType routeType, IEnumerable? extraConnections); 43 | 44 | 45 | 46 | Task AddRoute(int mapId,int soloarSystemId, bool global); 47 | 48 | Task DeleteRoute(int routeId); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveOAuthProvider/Validators/EveOnlineAccessTokenValidator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Options; 2 | using Microsoft.IdentityModel.JsonWebTokens; 3 | using Microsoft.IdentityModel.Tokens; 4 | 5 | 6 | namespace WHMapper.Services.EveOAuthProvider.Validators; 7 | 8 | public class EveOnlineAccessTokenValidator : IEveOnlineAccessTokenValidator 9 | { 10 | private readonly EVEOnlineAuthenticationOptions _options; 11 | private readonly ILogger _logger; 12 | 13 | public EveOnlineAccessTokenValidator(IOptionsMonitor options, ILogger logger) 14 | { 15 | _options = options.Get(EVEOnlineAuthenticationDefaults.AuthenticationScheme); 16 | _logger = logger; 17 | } 18 | 19 | 20 | public async Task ValidateAsync(string accessToken) 21 | { 22 | try 23 | { 24 | var response = await _options.Backchannel.GetStringAsync(_options.JWKEndpoint); 25 | var jwk = new JsonWebKeySet(response).Keys.First(); 26 | 27 | TokenValidationParameters tokenValidationParams = new TokenValidationParameters 28 | { 29 | ValidateAudience = true, 30 | ValidAudience = EVEOnlineAuthenticationDefaults.ValideAudience, 31 | 32 | ValidateIssuer = true, 33 | ValidIssuer = EVEOnlineAuthenticationDefaults.ValideIssuer, 34 | 35 | ValidateIssuerSigningKey = true, 36 | IssuerSigningKey = jwk, 37 | 38 | ClockSkew = TimeSpan.FromSeconds(2), // CCP's servers seem slightly ahead (~1s) 39 | }; 40 | 41 | 42 | var validationResult = await new JsonWebTokenHandler().ValidateTokenAsync(accessToken, tokenValidationParams); 43 | 44 | 45 | if(!validationResult.IsValid) 46 | { 47 | _logger.LogWarning(validationResult.Exception,"Access token is invalid"); 48 | 49 | } 50 | return validationResult.IsValid; 51 | } 52 | catch (Exception ex) 53 | { 54 | _logger.LogError(ex, "Failed to validate access token"); 55 | return false; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/WHMapper/Components/Layout/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row ::deep .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | text-decoration: none; 28 | } 29 | 30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { 31 | text-decoration: underline; 32 | } 33 | 34 | .top-row ::deep a:first-child { 35 | overflow: hidden; 36 | text-overflow: ellipsis; 37 | } 38 | 39 | @media (max-width: 640.98px) { 40 | .top-row { 41 | justify-content: space-between; 42 | } 43 | 44 | .top-row ::deep a, .top-row ::deep .btn-link { 45 | margin-left: 0; 46 | } 47 | } 48 | 49 | @media (min-width: 641px) { 50 | .page { 51 | flex-direction: row; 52 | } 53 | 54 | .sidebar { 55 | width: 250px; 56 | height: 100vh; 57 | position: sticky; 58 | top: 0; 59 | } 60 | 61 | .top-row { 62 | position: sticky; 63 | top: 0; 64 | z-index: 1; 65 | } 66 | 67 | .top-row.auth ::deep a:first-child { 68 | flex: 1; 69 | text-align: right; 70 | width: 0; 71 | } 72 | 73 | .top-row, article { 74 | padding-left: 2rem !important; 75 | padding-right: 1.5rem !important; 76 | } 77 | } 78 | 79 | #blazor-error-ui { 80 | background: lightyellow; 81 | bottom: 0; 82 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 83 | display: none; 84 | left: 0; 85 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 86 | position: fixed; 87 | width: 100%; 88 | z-index: 1000; 89 | } 90 | 91 | #blazor-error-ui .dismiss { 92 | cursor: pointer; 93 | position: absolute; 94 | right: 0.75rem; 95 | top: 0.5rem; 96 | } 97 | -------------------------------------------------------------------------------- /src/WHMapper/Models/DTO/EveMapper/EveEntity/WHEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using WHMapper.Models.DTO.EveMapper.Enums; 3 | 4 | namespace WHMapper.Models.DTO.EveMapper.EveEntity; 5 | 6 | public class WHEntity : AEveEntity 7 | { private const int DOGMA_ATTR_TARGET_SYSTEM_CLASS_FOR_WORMHOLES_ID = 1381; 8 | private const int DOGMA_ATTR_WORMHOLE_MAX_STABLE_MASS = 1383; 9 | private const int DOGMA_ATTR_WORMHOLE_MAX_JUMP_MASS = 1385; 10 | private const int DOGMA_ATTR_WORMHOLE_MAX_STABLE_TIME = 1382; //unit8id 3 value 1440 = 24h??? 11 | 12 | 13 | public float SystemTypeValue { get; private set; } 14 | public float MassMax {get; private set;} 15 | public float JumpMassMax {get; private set;} 16 | 17 | /// 18 | /// Time in minutes 19 | /// 24h = 1440 20 | /// 18h = 1080 21 | /// 22 | public float StableTime {get;private set;} 23 | 24 | public WHEntity(int id, WHMapper.Models.DTO.EveAPI.Universe.Type type) 25 | : base(id, type.Name[9..].Trim(), EveEntityEnums.Wormhole) 26 | { 27 | SystemTypeValue = 0; 28 | MassMax = 0; 29 | JumpMassMax = 0; 30 | StableTime = 0; 31 | if (type.DogmaAttributes != null) 32 | { 33 | SystemTypeValue = type.DogmaAttributes.Where(x => x.AttributeId == DOGMA_ATTR_TARGET_SYSTEM_CLASS_FOR_WORMHOLES_ID).Select(x => x.Value).FirstOrDefault(0); 34 | MassMax = type.DogmaAttributes.Where(x => x.AttributeId == DOGMA_ATTR_WORMHOLE_MAX_STABLE_MASS).Select(x => x.Value).FirstOrDefault(0); 35 | JumpMassMax = type.DogmaAttributes.Where(x => x.AttributeId == DOGMA_ATTR_WORMHOLE_MAX_JUMP_MASS).Select(x => x.Value).FirstOrDefault(0); 36 | StableTime = type.DogmaAttributes.Where(x => x.AttributeId == DOGMA_ATTR_WORMHOLE_MAX_STABLE_TIME).Select(x => x.Value).FirstOrDefault(0); 37 | } 38 | } 39 | 40 | [JsonConstructor] 41 | public WHEntity(int id, string name,float systemTypeValue, float massMax, float jumpMassMax, float stableTime) 42 | : base(id, name, EveEntityEnums.Wormhole) 43 | { 44 | SystemTypeValue = systemTypeValue; 45 | MassMax = massMax; 46 | JumpMassMax = jumpMassMax; 47 | StableTime = stableTime; 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveScoutAPI/EveScoutAPIServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Text.Json; 4 | using System.Text.Json.Serialization; 5 | using WHMapper.Models.DTO.EveScout; 6 | 7 | namespace WHMapper.Services.EveScoutAPI; 8 | 9 | public class EveScoutAPIServices : IEveScoutAPIServices 10 | { 11 | private readonly HttpClient _httpClient; 12 | private readonly JsonSerializerOptions _jsonSerializerOptions; 13 | 14 | public EveScoutAPIServices(HttpClient httpClient) 15 | { 16 | ArgumentNullException.ThrowIfNull(httpClient); 17 | 18 | _jsonSerializerOptions = new JsonSerializerOptions 19 | { 20 | NumberHandling = JsonNumberHandling.AllowReadingFromString 21 | }; 22 | _httpClient = httpClient; 23 | 24 | // Check if httpClient the base URL is set correctly 25 | if (!_httpClient.BaseAddress?.ToString().StartsWith(EveScoutAPIServiceConstants.EveScoutUrl) ?? true) 26 | { 27 | throw new ArgumentException("HttpClient base address must start with the EveScout API URL.", nameof(httpClient)); 28 | } 29 | } 30 | 31 | public Task?> GetTheraSystemsAsync() 32 | { 33 | return Execute>("v2/public/signatures?system_name=thera"); 34 | } 35 | 36 | public Task?> GetTurnurSystemsAsync() 37 | { 38 | return Execute>("v2/public/signatures?system_name=turnur"); 39 | } 40 | 41 | private async Task Execute(string uri) 42 | { 43 | HttpResponseMessage? response = await _httpClient.GetAsync(uri).ConfigureAwait(false); 44 | 45 | if (response != null && response.StatusCode != HttpStatusCode.NoContent && (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.Accepted)) 46 | { 47 | string result = response.Content.ReadAsStringAsync().Result; 48 | if (string.IsNullOrEmpty(result)) 49 | return default(T); 50 | else 51 | return JsonSerializer.Deserialize(result, _jsonSerializerOptions); 52 | } 53 | else 54 | return default(T); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/WHMapper/Services/EveAPI/Search/SearchServices.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using WHMapper.Models.DTO; 3 | using WHMapper.Models.DTO.EveAPI.Search; 4 | 5 | namespace WHMapper.Services.EveAPI.Search 6 | { 7 | public class SearchServices : EveApiServiceBase, ISearchServices 8 | { 9 | public SearchServices(HttpClient httpClient, UserToken? userToken = null) : base(httpClient, userToken) 10 | { 11 | } 12 | 13 | public async Task> SearchAlliance(string searchValue, bool isStrict = false) 14 | { 15 | if (this.UserToken != null) 16 | { 17 | return await base.Execute(RequestSecurity.Authenticated, RequestMethod.Get, string.Format("/v3/characters/{0}/search/?datasource=tranquility&search={1}&categories=alliance&strict={2}", UserToken.AccountId, searchValue, isStrict)); 18 | } 19 | return Result.Failure("UserToken is required for authenticated requests", (int)HttpStatusCode.Unauthorized); 20 | } 21 | 22 | public async Task> SearchCharacter(string searchValue, bool isStrict = false) 23 | { 24 | if (this.UserToken != null) 25 | { 26 | return await base.Execute(RequestSecurity.Authenticated, RequestMethod.Get, string.Format("/v3/characters/{0}/search/?datasource=tranquility&search={1}&categories=character&strict={2}", UserToken.AccountId, searchValue, isStrict)); 27 | } 28 | return Result.Failure("UserToken is required for authenticated requests", (int)HttpStatusCode.Unauthorized); 29 | } 30 | 31 | public async Task> SearchCorporation(string searchValue, bool isStrict = false) 32 | { 33 | if (this.UserToken != null) 34 | { 35 | return await base.Execute(RequestSecurity.Authenticated, RequestMethod.Get, string.Format("/v3/characters/{0}/search/?datasource=tranquility&search={1}&categories=corporation&strict={2}", UserToken.AccountId, searchValue, isStrict)); 36 | } 37 | return Result.Failure("UserToken is required for authenticated requests", (int)HttpStatusCode.Unauthorized); 38 | } 39 | } 40 | } --------------------------------------------------------------------------------