diff --git a/Ombi/Build/publish.bat b/Ombi/Build/publish.bat index 48cc28c2a..e9af4b38c 100644 --- a/Ombi/Build/publish.bat +++ b/Ombi/Build/publish.bat @@ -1,9 +1,9 @@ ;https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/ cd .. dotnet restore -dotnet publish -c Release -r win10-x64 -dotnet publish -c Release -r osx.10.12-x64 -dotnet publish -c Release -r ubuntu.16.10-x64 -dotnet publish -c Release -r debian.8-x64 +dotnet publish -c Release /p:AppRuntimeIdentifier=win10-x64 +dotnet publish -c Release /p:AppRuntimeIdentifier=osx.10.12-x64 +dotnet publish -c Release /p:AppRuntimeIdentifier=ubuntu.16.10-x64 +dotnet publish -c Release /p:AppRuntimeIdentifier=debian.8-x64 exit \ No newline at end of file diff --git a/Ombi/Ombi.Core/Settings/ISettingsService.cs b/Ombi/Ombi.Core/Settings/ISettingsService.cs new file mode 100644 index 000000000..f781676a0 --- /dev/null +++ b/Ombi/Ombi.Core/Settings/ISettingsService.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; + +namespace Ombi.Core.Settings +{ + public interface ISettingsService + { + T GetSettings(); + Task GetSettingsAsync(); + bool SaveSettings(T model); + Task SaveSettingsAsync(T model); + bool Delete(T model); + Task DeleteAsync(T model); + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Core/Settings/Models/Settings.cs b/Ombi/Ombi.Core/Settings/Models/Settings.cs new file mode 100644 index 000000000..d24438223 --- /dev/null +++ b/Ombi/Ombi.Core/Settings/Models/Settings.cs @@ -0,0 +1,7 @@ +namespace Ombi.Core.Settings.Models +{ + public class Settings + { + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Core/Settings/SettingsService.cs b/Ombi/Ombi.Core/Settings/SettingsService.cs new file mode 100644 index 000000000..c796710fa --- /dev/null +++ b/Ombi/Ombi.Core/Settings/SettingsService.cs @@ -0,0 +1,129 @@ +using System.Threading.Tasks; +using Newtonsoft.Json; +using Ombi.Helpers; +using Ombi.Store.Entities; +using Ombi.Store.Repository; + +namespace Ombi.Core.Settings +{ + public class SettingsServiceV2 : ISettingsService + where T : Models.Settings, new() + { + + public SettingsServiceV2(ISettingsRepository repo) + { + Repo = repo; + EntityName = typeof(T).Name; + } + + private ISettingsRepository Repo { get; } + private string EntityName { get; } + + public T GetSettings() + { + var result = Repo.Get(EntityName); + if (result == null) + { + return new T(); + } + result.Content = DecryptSettings(result); + var obj = string.IsNullOrEmpty(result.Content) ? null : JsonConvert.DeserializeObject(result.Content, SerializerSettings.Settings); + + var model = obj; + + return model; + } + + public async Task GetSettingsAsync() + { + var result = await Repo.GetAsync(EntityName).ConfigureAwait(false); + if (result == null) + { + return new T(); + } + result.Content = DecryptSettings(result); + return string.IsNullOrEmpty(result.Content) ? null : JsonConvert.DeserializeObject(result.Content, SerializerSettings.Settings); + } + + public bool SaveSettings(T model) + { + var entity = Repo.Get(EntityName); + + if (entity == null) + { + var newEntity = model; + + var settings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(newEntity, SerializerSettings.Settings) }; + settings.Content = EncryptSettings(settings); + var insertResult = Repo.Insert(settings); + + return insertResult != null; + } + + + var modified = model; + modified.Id = entity.Id; + + var globalSettings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(modified, SerializerSettings.Settings), Id = entity.Id }; + globalSettings.Content = EncryptSettings(globalSettings); + Repo.Update(globalSettings); + + return true; + } + + public async Task SaveSettingsAsync(T model) + { + var entity = await Repo.GetAsync(EntityName); + + if (entity == null) + { + var newEntity = model; + + var settings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(newEntity, SerializerSettings.Settings) }; + settings.Content = EncryptSettings(settings); + var insertResult = await Repo.InsertAsync(settings).ConfigureAwait(false); + + return insertResult != null; + } + + var modified = model; + modified.Id = entity.Id; + + var globalSettings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(modified, SerializerSettings.Settings), Id = entity.Id }; + globalSettings.Content = EncryptSettings(globalSettings); + await Repo.UpdateAsync(globalSettings).ConfigureAwait(false); + + return true; + } + + public void Delete(T model) + { + var entity = Repo.Get(EntityName); + if (entity != null) + { + Repo.Delete(entity); + } + + } + + public async Task DeleteAsync(T model) + { + var entity = Repo.Get(EntityName); + if (entity != null) + { + await Repo.DeleteAsync(entity); + } + + } + + private string EncryptSettings(GlobalSettings settings) + { + return StringCipher.Encrypt(settings.Content, settings.SettingsName); + } + + private string DecryptSettings(GlobalSettings settings) + { + return StringCipher.Decrypt(settings.Content, settings.SettingsName); + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.DependencyInjection/IocExtensions.cs b/Ombi/Ombi.DependencyInjection/IocExtensions.cs new file mode 100644 index 000000000..189c58b3b --- /dev/null +++ b/Ombi/Ombi.DependencyInjection/IocExtensions.cs @@ -0,0 +1,57 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.DependencyInjection; +using Ombi.Core; +using Ombi.Core.Engine; +using Ombi.Core.Models.Requests; +using Ombi.Core.Requests.Models; +using Ombi.Core.Settings; +using Ombi.Store.Context; +using Ombi.Store.Repository; +using Ombi.TheMovieDbApi; + +namespace Ombi.DependencyInjection +{ + [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] + public static class IocExtensions + { + public static IServiceCollection RegisterDependencies(this IServiceCollection services) + { + services.RegisterEngines(); + services.RegisterApi(); + services.RegisterServices(); + services.RegisterStore(); + + return services; + } + + public static IServiceCollection RegisterEngines(this IServiceCollection services) + { + services.AddTransient(); + services.AddTransient(); + return services; + } + + public static IServiceCollection RegisterApi(this IServiceCollection services) + { + services.AddTransient(); + return services; + } + + public static IServiceCollection RegisterStore(this IServiceCollection services) + { + services.AddEntityFrameworkSqlite().AddDbContext(); + + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(typeof(ISettingsService<>), typeof(SettingsServiceV2<>)); + return services; + } + public static IServiceCollection RegisterServices(this IServiceCollection services) + { + services.AddTransient(); + return services; + } + } +} diff --git a/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj new file mode 100644 index 000000000..0be698b01 --- /dev/null +++ b/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -0,0 +1,17 @@ + + + + netstandard1.4 + + + + + + + + + ..\..\..\..\..\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + + \ No newline at end of file diff --git a/Ombi/Ombi.Helpers/SerializerSettings.cs b/Ombi/Ombi.Helpers/SerializerSettings.cs new file mode 100644 index 000000000..688624f27 --- /dev/null +++ b/Ombi/Ombi.Helpers/SerializerSettings.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace Ombi.Helpers +{ + public static class SerializerSettings + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + Formatting = Formatting.None, + //TypeNameHandling = TypeNameHandling.Objects, + //TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple, + NullValueHandling = NullValueHandling.Ignore + }; + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Helpers/StringCipher.cs b/Ombi/Ombi.Helpers/StringCipher.cs new file mode 100644 index 000000000..152dc3f0d --- /dev/null +++ b/Ombi/Ombi.Helpers/StringCipher.cs @@ -0,0 +1,120 @@ +using System; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace Ombi.Helpers +{ + public class StringCipher + { + // This constant determines the number of iterations for the password bytes generation function. + private const int DerivationIterations = 1000; + // This constant is used to determine the keysize of the encryption algorithm in bits. + // We divide this by 8 within the code below to get the equivalent number of bytes. + private const int Keysize = 256; + + /// + /// Decrypts the specified cipher text. + /// + /// The cipher text. + /// The pass phrase. + /// + public static string Decrypt(string cipherText, string passPhrase) + { + // Get the complete stream of bytes that represent: + // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText] + var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText); + // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes. + var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray(); + // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes. + var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray(); + // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string. + var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray(); + + using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) + { + var keyBytes = password.GetBytes(Keysize / 8); + var aes = Aes.Create(); + using (var symmetricKey = new RijndaelManaged()) + { + symmetricKey.BlockSize = 256; + symmetricKey.Mode = CipherMode.CBC; + symmetricKey.Padding = PaddingMode.PKCS7; + using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes)) + { + using (var memoryStream = new MemoryStream(cipherTextBytes)) + { + using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) + { + var plainTextBytes = new byte[cipherTextBytes.Length]; + var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); + memoryStream.Close(); + cryptoStream.Close(); + return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); + } + } + } + } + } + } + + /// + /// Encrypts the specified plain text. + /// + /// The plain text. + /// The pass phrase. + /// + public static string Encrypt(string plainText, string passPhrase) + { + // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text + // so that the same Salt and IV values can be used when decrypting. + var saltStringBytes = Generate256BitsOfRandomEntropy(); + var ivStringBytes = Generate256BitsOfRandomEntropy(); + var plainTextBytes = Encoding.UTF8.GetBytes(plainText); + using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) + { + var keyBytes = password.GetBytes(Keysize / 8); + using (var symmetricKey = new RijndaelManaged()) + { + symmetricKey.BlockSize = 256; + symmetricKey.Mode = CipherMode.CBC; + symmetricKey.Padding = PaddingMode.PKCS7; + using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes)) + { + using (var memoryStream = new MemoryStream()) + { + using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) + { + cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); + cryptoStream.FlushFinalBlock(); + // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes. + var cipherTextBytes = saltStringBytes; + cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray(); + cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray(); + memoryStream.Close(); + cryptoStream.Close(); + return Convert.ToBase64String(cipherTextBytes); + } + } + } + } + } + } + + /// + /// Generate256s the bits of random entropy. + /// + /// + private static byte[] Generate256BitsOfRandomEntropy() + { + var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits. + using (var rngCsp = new RNGCryptoServiceProvider()) + { + // Fill the array with cryptographically secure random bytes. + rngCsp.GetBytes(randomBytes); + } + return randomBytes; + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Store/Context/IOmbiContext.cs b/Ombi/Ombi.Store/Context/IOmbiContext.cs index c9dff7bca..1d555253d 100644 --- a/Ombi/Ombi.Store/Context/IOmbiContext.cs +++ b/Ombi/Ombi.Store/Context/IOmbiContext.cs @@ -11,5 +11,6 @@ namespace Ombi.Store.Context int SaveChanges(); Task SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); DbSet Requests { get; set; } + DbSet Settings { get; set; } } } \ No newline at end of file diff --git a/Ombi/Ombi.Store/Context/OmbiContext.cs b/Ombi/Ombi.Store/Context/OmbiContext.cs index ec8903d3a..9a97ac69f 100644 --- a/Ombi/Ombi.Store/Context/OmbiContext.cs +++ b/Ombi/Ombi.Store/Context/OmbiContext.cs @@ -5,17 +5,17 @@ namespace Ombi.Store.Context { public class OmbiContext : DbContext, IOmbiContext { - private static bool _created = false; + private static bool _created; public OmbiContext() { - if(!_created) - { - _created = true; - //Database.EnsureDeleted(); - Database.EnsureCreated(); - } + if (_created) return; + + _created = true; + Database.EnsureCreated(); + Database.Migrate(); } public DbSet Requests { get; set; } + public DbSet Settings { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/Ombi/Ombi.Store/Entities/GlobalSettings.cs b/Ombi/Ombi.Store/Entities/GlobalSettings.cs new file mode 100644 index 000000000..bc651d214 --- /dev/null +++ b/Ombi/Ombi.Store/Entities/GlobalSettings.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Ombi.Store.Entities +{ + [Table("GlobalSettings")] + public class GlobalSettings : Entity + { + public string Content { get; set; } + public string SettingsName { get; set; } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Store/Repository/ISettingsRepository.cs b/Ombi/Ombi.Store/Repository/ISettingsRepository.cs new file mode 100644 index 000000000..2ed8e7fa0 --- /dev/null +++ b/Ombi/Ombi.Store/Repository/ISettingsRepository.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public interface ISettingsRepository + { + /// + /// Inserts the specified entity. + /// + /// The entity. + GlobalSettings Insert(GlobalSettings entity); + Task InsertAsync(GlobalSettings entity); + + /// + /// Gets all. + /// + /// + IEnumerable GetAll(); + Task> GetAllAsync(); + + /// + /// Gets the specified identifier. + /// + /// Name of the settings. + /// + GlobalSettings Get(string settingsName); + Task GetAsync(string settingsName); + + /// + /// Deletes the specified entity. + /// + /// The entity. + /// + Task DeleteAsync(GlobalSettings entity); + void Delete(GlobalSettings entity); + + /// + /// Updates the specified entity. + /// + /// The entity. + /// + Task UpdateAsync(GlobalSettings entity); + void Update(GlobalSettings entity); + + + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs b/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs new file mode 100644 index 000000000..987276a55 --- /dev/null +++ b/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Store.Context; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public class SettingsJsonRepository : ISettingsRepository + { + public SettingsJsonRepository(IOmbiContext ctx) + { + Db = ctx; + } + + private IOmbiContext Db { get; } + + public GlobalSettings Insert(GlobalSettings entity) + { + + var settings = Db.Settings.Add(entity); + Db.SaveChanges(); + return settings.Entity; + + } + + public async Task InsertAsync(GlobalSettings entity) + { + + var settings = await Db.Settings.AddAsync(entity).ConfigureAwait(false); + await Db.SaveChangesAsync().ConfigureAwait(false); + return settings.Entity; + } + + public IEnumerable GetAll() + { + + var page = Db.Settings.ToList(); + return page; + + } + + public async Task> GetAllAsync() + { + var page = await Db.Settings.ToListAsync(); + return page; + } + + public GlobalSettings Get(string pageName) + { + return Db.Settings.FirstOrDefault(x => x.SettingsName == pageName); + } + + public async Task GetAsync(string settingsName) + { + return await Db.Settings.FirstOrDefaultAsync(x => x.SettingsName == settingsName); + } + + public async Task DeleteAsync(GlobalSettings entity) + { + Db.Settings.Remove(entity); + await Db.SaveChangesAsync(); + } + + public async Task UpdateAsync(GlobalSettings entity) + { + Db.Settings.Update(entity); + await Db.SaveChangesAsync(); + } + + public void Delete(GlobalSettings entity) + { + Db.Settings.Remove(entity); + Db.SaveChanges(); + } + + public void Update(GlobalSettings entity) + { + Db.Settings.Update(entity); + Db.SaveChanges(); + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.sln b/Ombi/Ombi.sln index 8857dcc07..bd42c7e32 100644 --- a/Ombi/Ombi.sln +++ b/Ombi/Ombi.sln @@ -24,6 +24,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Helpers", "Ombi.Helper EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Store", "Ombi.Store\Ombi.Store.csproj", "{68086581-1EFD-4390-8100-47F87D1CB628}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.DependencyInjection", "Ombi.DependencyInjection\Ombi.DependencyInjection.csproj", "{B39E4558-C557-48E7-AA74-19C5CD809617}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -54,6 +56,10 @@ Global {68086581-1EFD-4390-8100-47F87D1CB628}.Debug|Any CPU.Build.0 = Debug|Any CPU {68086581-1EFD-4390-8100-47F87D1CB628}.Release|Any CPU.ActiveCfg = Release|Any CPU {68086581-1EFD-4390-8100-47F87D1CB628}.Release|Any CPU.Build.0 = Release|Any CPU + {B39E4558-C557-48E7-AA74-19C5CD809617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B39E4558-C557-48E7-AA74-19C5CD809617}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B39E4558-C557-48E7-AA74-19C5CD809617}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Ombi/Ombi/Ombi.csproj b/Ombi/Ombi/Ombi.csproj index bfb0278da..9c3dab512 100644 --- a/Ombi/Ombi/Ombi.csproj +++ b/Ombi/Ombi/Ombi.csproj @@ -19,12 +19,19 @@ - + + + + + + + + diff --git a/Ombi/Ombi/Startup.cs b/Ombi/Ombi/Startup.cs index 7fb5c4e52..defdcce82 100644 --- a/Ombi/Ombi/Startup.cs +++ b/Ombi/Ombi/Startup.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; +using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -12,13 +8,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; -using Ombi.Core; -using Ombi.Core.Engine; -using Ombi.Core.Models.Requests; -using Ombi.Core.Requests.Models; +using Ombi.DependencyInjection; using Ombi.Store.Context; -using Ombi.Store.Repository; -using Ombi.TheMovieDbApi; namespace Ombi { @@ -28,17 +19,11 @@ namespace Ombi { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddJsonFile("appsettings.json", false, true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true) .AddEnvironmentVariables(); Configuration = builder.Build(); - using (var ctx = new OmbiContext()) - { - ctx.Database.EnsureCreated(); - ctx.Database.Migrate(); - } - } public IConfigurationRoot Configuration { get; } @@ -48,13 +33,7 @@ namespace Ombi { // Add framework services. services.AddMvc(); - services.AddEntityFrameworkSqlite().AddDbContext(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + services.RegisterDependencies(); // Ioc and EF } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -66,7 +45,6 @@ namespace Ombi if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); - app.UseBrowserLink(); } else { diff --git a/Ombi/Ombi/app/app.component.html b/Ombi/Ombi/app/app.component.html index d20236536..4311d459d 100644 --- a/Ombi/Ombi/app/app.component.html +++ b/Ombi/Ombi/app/app.component.html @@ -15,32 +15,13 @@ + -
diff --git a/Ombi/Ombi/app/app.component.ts b/Ombi/Ombi/app/app.component.ts index f41eaa8c3..af6818c55 100644 --- a/Ombi/Ombi/app/app.component.ts +++ b/Ombi/Ombi/app/app.component.ts @@ -1,5 +1,4 @@ import { Component } from '@angular/core'; -import { MenuItem } from 'primeng/components/common/api'; @Component({ selector: 'ombi', @@ -7,17 +6,5 @@ import { MenuItem } from 'primeng/components/common/api'; templateUrl: './app.component.html' }) export class AppComponent { - private items: MenuItem[]; - ngOnInit() { - this.items = [ - { - label: 'Ombi', - routerLink: ['/'] - }, - { - label: 'Search', - routerLink: ['/search'] - }, - ]; - } + } \ No newline at end of file diff --git a/Ombi/Ombi/app/app.module.ts b/Ombi/Ombi/app/app.module.ts index 2bc3967a6..ea5d2123c 100644 --- a/Ombi/Ombi/app/app.module.ts +++ b/Ombi/Ombi/app/app.module.ts @@ -15,8 +15,10 @@ import { PageNotFoundComponent } from './errors/not-found.component'; import { SearchService } from './services/search.service'; import { RequestService } from './services/request.service'; +// Modules +import { SettingsModule } from './settings/settings.module'; + import { ButtonModule } from 'primeng/primeng'; -import { MenubarModule } from 'primeng/components/menubar/menubar'; import { GrowlModule } from 'primeng/components/growl/growl'; const routes: Routes = [ @@ -30,10 +32,10 @@ const routes: Routes = [ BrowserModule, BrowserAnimationsModule, HttpModule, - MenubarModule, GrowlModule, ButtonModule, - FormsModule + FormsModule, + SettingsModule ], declarations: [ AppComponent, diff --git a/Ombi/Ombi/app/settings/ombi/ombi.component.html b/Ombi/Ombi/app/settings/ombi/ombi.component.html new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Ombi/Ombi/app/settings/ombi/ombi.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Ombi/Ombi/app/settings/ombi/ombi.component.ts b/Ombi/Ombi/app/settings/ombi/ombi.component.ts new file mode 100644 index 000000000..0d4746eec --- /dev/null +++ b/Ombi/Ombi/app/settings/ombi/ombi.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +@Component({ + selector: 'ombi', + moduleId: module.id, + templateUrl: './ombi.component.html', +}) +export class OmbiComponent { + + + +} \ No newline at end of file diff --git a/Ombi/Ombi/app/settings/settings.module.ts b/Ombi/Ombi/app/settings/settings.module.ts new file mode 100644 index 000000000..588cfb602 --- /dev/null +++ b/Ombi/Ombi/app/settings/settings.module.ts @@ -0,0 +1,29 @@ +import { NgModule, } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule, Routes } from '@angular/router'; + +import { OmbiComponent } from './ombi/ombi.component' + + +const routes: Routes = [ + { path: 'Settings/Ombi', component: OmbiComponent } +]; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + RouterModule.forChild(routes), + + ], + declarations: [ + OmbiComponent + ], + exports: [ + RouterModule + ], + providers: [ + ] +}) +export class SettingsModule { } \ No newline at end of file