mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-31 12:00:06 -07:00
Finsihed adding preset themes.
Added query string support for api key #1689 Added swedish lang #1691
This commit is contained in:
parent
9252bbf110
commit
aad5a71c98
11 changed files with 106 additions and 114 deletions
|
@ -19,7 +19,7 @@ namespace Ombi.Api.Github
|
|||
|
||||
public async Task<List<CakeThemes>> GetCakeThemes()
|
||||
{
|
||||
var request = new Request("repos/leram84/layer.Cake/contents/ombi/themes", BaseUrl, HttpMethod.Get);
|
||||
var request = new Request("repos/tidusjar/layer.Cake/contents/ombi/themes", BaseUrl, HttpMethod.Get);
|
||||
request.AddHeader("Accept", "application/vnd.github.v3+json");
|
||||
request.AddHeader("User-Agent", "Ombi");
|
||||
return await _api.Request<List<CakeThemes>>(request);
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Ombi.Settings.Settings.Models
|
|||
public string PresetThemeContent { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string PresetThemeVersionVersion
|
||||
public string PresetThemeVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
@ -26,13 +26,13 @@ export class AppComponent implements OnInit {
|
|||
private readonly settingsService: SettingsService,
|
||||
private readonly jobService: JobService,
|
||||
public readonly translate: TranslateService) {
|
||||
this.translate.addLangs(["en", "de", "fr","da","es","it","nl"]);
|
||||
this.translate.addLangs(["en", "de", "fr","da","es","it","nl","sv"]);
|
||||
// this language will be used as a fallback when a translation isn't found in the current language
|
||||
this.translate.setDefaultLang("en");
|
||||
|
||||
// See if we can match the supported langs with the current browser lang
|
||||
const browserLang: string = translate.getBrowserLang();
|
||||
this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl/) ? browserLang : "en");
|
||||
this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl|sv/) ? browserLang : "en");
|
||||
}
|
||||
|
||||
public ngOnInit() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<fieldset *ngIf="settings">
|
||||
<legend>Customization</legend>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-5">
|
||||
<div class="form-group">
|
||||
<label for="applicationName" class="control-label">Application Name</label>
|
||||
<div>
|
||||
|
@ -27,6 +27,12 @@
|
|||
tooltipPosition="top" pTooltip="Use a URL e.g. www.google.com/logo.png">
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="settings.logo" class="form-group">
|
||||
<label for="logo" class="control-label">Logo Preview:</label>
|
||||
<div>
|
||||
<img [src]="settings.logo" style="width: 300px" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -46,7 +52,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <div class="col-md-6">
|
||||
<div class="col-md-7">
|
||||
<div *ngIf="themes">
|
||||
<div class="form-group">
|
||||
<label for="presetTheme" class="control-label">Preset Themes</label>
|
||||
|
@ -56,19 +62,14 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<textarea rows="4" type="text" class="form-control-custom form-control " id="themeContent" name="themeContent" [(ngModel)]="settings.presetThemeContent"> {{settings.presetThemeContent}} </textarea>
|
||||
<div class="form-group" *ngIf="settings.presetThemeContent">
|
||||
<textarea rows="25" type="text" class="form-control-custom form-control " id="themeContent" name="themeContent" [(ngModel)]="settings.presetThemeContent"> {{settings.presetThemeContent}} </textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div *ngIf="settings.logo" class="form-group">
|
||||
<label for="logo" class="control-label">Logo Preview:</label>
|
||||
<div>
|
||||
<img [src]="settings.logo" style="width: 300px" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
|
@ -19,6 +19,18 @@ export class CustomizationComponent implements OnInit {
|
|||
this.settings = x;
|
||||
this.settingsService.getThemes().subscribe(t => {
|
||||
this.themes = t;
|
||||
|
||||
const existingTheme = this.themes.filter((item) => {
|
||||
return item.fullName === this.settings.presetThemeName;
|
||||
})[0];
|
||||
|
||||
if(existingTheme) {
|
||||
const index = this.themes.indexOf(existingTheme, 0);
|
||||
if (index > -1) {
|
||||
this.themes.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(x.hasPresetTheme) {
|
||||
this.themes.unshift({displayName: x.presetThemeDisplayName, fullName: x.presetThemeName, url: "", version: x.presetThemeVersion});
|
||||
} else {
|
||||
|
@ -45,9 +57,9 @@ export class CustomizationComponent implements OnInit {
|
|||
return val.fullName === selectedThemeFullName;
|
||||
});
|
||||
|
||||
// if(selectedTheme[0].fullName === this.settings.presetThemeName) {
|
||||
// return;
|
||||
// }
|
||||
if(selectedTheme[0].fullName === this.settings.presetThemeName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.presetThemeName = selectedThemeFullName;
|
||||
this.settingsService.getThemeContent(selectedTheme[0].url).subscribe(x => {
|
||||
|
|
|
@ -259,6 +259,7 @@ namespace Ombi.Controllers
|
|||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("themecontent")]
|
||||
[AllowAnonymous]
|
||||
public async Task<string> GetThemeContent([FromQuery]string url)
|
||||
{
|
||||
var content = await _githubApi.GetThemesRawContent(url);
|
||||
|
|
|
@ -194,7 +194,7 @@ namespace Ombi
|
|||
|
||||
app.UseAuthentication();
|
||||
|
||||
ApiKeyMiddlewear(app, serviceProvider);
|
||||
app.ApiKeyMiddlewear(serviceProvider);
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
|
@ -213,46 +213,6 @@ namespace Ombi
|
|||
defaults: new { controller = "Home", action = "Index" });
|
||||
});
|
||||
}
|
||||
|
||||
private static void ApiKeyMiddlewear(IApplicationBuilder app, IServiceProvider serviceProvider)
|
||||
{
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
|
||||
{
|
||||
// Let's check if this is an API Call
|
||||
if (context.Request.Headers["ApiKey"].Any())
|
||||
{
|
||||
// validate the supplied API key
|
||||
// Validate it
|
||||
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
|
||||
var settingsProvider = serviceProvider.GetService<ISettingsService<OmbiSettings>>();
|
||||
var ombiSettings = settingsProvider.GetSettings();
|
||||
var valid = ombiSettings.ApiKey.Equals(headerKey, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (!valid)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
await context.Response.WriteAsync("Invalid API Key");
|
||||
}
|
||||
else
|
||||
{
|
||||
var identity = new GenericIdentity("API");
|
||||
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
|
||||
context.User = principal;
|
||||
await next();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Ombi.Config;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Models.Identity;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
|
||||
namespace Ombi
|
||||
|
@ -103,5 +112,58 @@ namespace Ombi
|
|||
x.TokenValidationParameters = tokenValidationParameters;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static void ApiKeyMiddlewear(this IApplicationBuilder app, IServiceProvider serviceProvider)
|
||||
{
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
|
||||
{
|
||||
// Let's check if this is an API Call
|
||||
if (context.Request.Headers["ApiKey"].Any())
|
||||
{
|
||||
// validate the supplied API key
|
||||
// Validate it
|
||||
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
|
||||
await ValidateApiKey(serviceProvider, context, next, headerKey);
|
||||
}
|
||||
else if (context.Request.Query.ContainsKey("apikey"))
|
||||
{
|
||||
if (context.Request.Query.TryGetValue("apikey", out var queryKey))
|
||||
{
|
||||
await ValidateApiKey(serviceProvider, context, next, queryKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static async Task ValidateApiKey(IServiceProvider serviceProvider, HttpContext context, Func<Task> next, string key)
|
||||
{
|
||||
var settingsProvider = serviceProvider.GetService<ISettingsService<OmbiSettings>>();
|
||||
var ombiSettings = settingsProvider.GetSettings();
|
||||
var valid = ombiSettings.ApiKey.Equals(key, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (!valid)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
await context.Response.WriteAsync("Invalid API Key");
|
||||
}
|
||||
else
|
||||
{
|
||||
var identity = new GenericIdentity("API");
|
||||
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
|
||||
context.User = principal;
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,6 +56,13 @@
|
|||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
@{
|
||||
if (customization.HasPresetTheme)
|
||||
{
|
||||
<style>
|
||||
@Html.Raw(customization.PresetThemeContent)
|
||||
</style>
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(customization.CustomCssLink))
|
||||
{
|
||||
<link rel="stylesheet" href="@customization.CustomCssLink" asp-append-version="true"/>
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
{
|
||||
"Login": {
|
||||
"SignInButton": "crwdns37:0crwdne37:0",
|
||||
"UsernamePlaceholder": "crwdns38:0crwdne38:0",
|
||||
"PasswordPlaceholder": "crwdns39:0crwdne39:0",
|
||||
"RememberMe": "crwdns40:0crwdne40:0",
|
||||
"ForgottenPassword": "crwdns41:0crwdne41:0",
|
||||
"Errors": {
|
||||
"IncorrectCredentials": "crwdns71:0crwdne71:0"
|
||||
}
|
||||
},
|
||||
"Common": {
|
||||
"ContinueButton": "crwdns42:0crwdne42:0",
|
||||
"Errors": {
|
||||
"Validation": "crwdns72:0crwdne72:0"
|
||||
}
|
||||
},
|
||||
"PasswordReset": {
|
||||
"EmailAddressPlaceholder": "crwdns43:0crwdne43:0",
|
||||
"ResetPasswordButton": "crwdns44:0crwdne44:0"
|
||||
},
|
||||
"LandingPage": {
|
||||
"OnlineHeading": "crwdns45:0crwdne45:0",
|
||||
"OnlineParagraph": "crwdns46:0crwdne46:0",
|
||||
"PartiallyOnlineHeading": "crwdns47:0crwdne47:0",
|
||||
"PartiallyOnlineParagraph": "crwdns48:0crwdne48:0",
|
||||
"MultipleServersUnavailable": "crwdns49:0{{serversUnavailable}}crwdnd49:0{{totalServers}}crwdne49:0",
|
||||
"SingleServerUnavailable": "crwdns50:0{{serversUnavailable}}crwdnd50:0{{totalServers}}crwdne50:0",
|
||||
"OfflineHeading": "crwdns51:0crwdne51:0",
|
||||
"OfflineParagraph": "crwdns52:0crwdne52:0",
|
||||
"CheckPageForUpdates": "crwdns73:0crwdne73:0"
|
||||
},
|
||||
"NavigationBar": {
|
||||
"Search": "crwdns54:0crwdne54:0",
|
||||
"Requests": "crwdns55:0crwdne55:0",
|
||||
"UserManagement": "crwdns56:0crwdne56:0",
|
||||
"Donate": "crwdns57:0crwdne57:0",
|
||||
"DonateTooltip": "crwdns58:0crwdne58:0",
|
||||
"UpdateAvailableTooltip": "crwdns59:0crwdne59:0",
|
||||
"Settings": "crwdns60:0crwdne60:0",
|
||||
"Welcome": "crwdns61:0{{username}}crwdne61:0",
|
||||
"UpdateDetails": "crwdns62:0crwdne62:0",
|
||||
"Logout": "crwdns63:0crwdne63:0",
|
||||
"Language": {
|
||||
"English": "crwdns64:0crwdne64:0",
|
||||
"French": "crwdns65:0crwdne65:0",
|
||||
"Spanish": "crwdns66:0crwdne66:0",
|
||||
"German": "crwdns67:0crwdne67:0",
|
||||
"Italian": "crwdns68:0crwdne68:0",
|
||||
"Danish": "crwdns69:0crwdne69:0",
|
||||
"Dutch": "crwdns70:0crwdne70:0"
|
||||
}
|
||||
}
|
||||
}
|
3
src/Ombi/wwwroot/translations/sv.json
Normal file
3
src/Ombi/wwwroot/translations/sv.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue