mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-14 02:26:55 -07:00
Fixed a potential security vulnerability
This commit is contained in:
parent
60aa1c9fb0
commit
8e36a97f4e
9 changed files with 16 additions and 175 deletions
|
@ -24,16 +24,5 @@ namespace Ombi.Api.Github
|
|||
request.AddHeader("User-Agent", "Ombi");
|
||||
return await _api.Request<List<CakeThemes>>(request);
|
||||
}
|
||||
|
||||
public async Task<string> GetThemesRawContent(string url)
|
||||
{
|
||||
var sections = url.Split('/');
|
||||
var lastPart = sections.Last();
|
||||
url = url.Replace(lastPart, string.Empty);
|
||||
var request = new Request(lastPart, url, HttpMethod.Get);
|
||||
request.AddHeader("Accept", "application/vnd.github.v3+json");
|
||||
request.AddHeader("User-Agent", "Ombi");
|
||||
return await _api.RequestContent(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,5 @@ namespace Ombi.Api.Github
|
|||
public interface IGithubApi
|
||||
{
|
||||
Task<List<CakeThemes>> GetCakeThemes();
|
||||
Task<string> GetThemesRawContent(string url);
|
||||
}
|
||||
}
|
|
@ -1,55 +1,16 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Helpers;
|
||||
|
||||
namespace Ombi.Settings.Settings.Models
|
||||
namespace Ombi.Settings.Settings.Models
|
||||
{
|
||||
public class CustomizationSettings : Settings
|
||||
{
|
||||
public string ApplicationName { get; set; }
|
||||
public string ApplicationUrl { get; set; }
|
||||
public string CustomCssLink { get; set; }
|
||||
public string CustomCss { get; set; }
|
||||
public bool EnableCustomDonations { get; set; }
|
||||
public string CustomDonationUrl { get; set; }
|
||||
public string CustomDonationMessage { get; set; }
|
||||
public string Logo { get; set; }
|
||||
|
||||
public string PresetThemeName { get; set; }
|
||||
public string PresetThemeContent { get; set; }
|
||||
public bool RecentlyAddedPage { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string PresetThemeVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HasPresetTheme)
|
||||
{
|
||||
var parts = PresetThemeName.Split('-');
|
||||
return parts[3].Replace(".css", string.Empty);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
public string PresetThemeDisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HasPresetTheme)
|
||||
{
|
||||
var parts = PresetThemeName.Split('-');
|
||||
return parts[1];
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
public bool HasPresetTheme => PresetThemeName.HasValue() || PresetThemeContent.HasValue();
|
||||
|
||||
public void AddToUrl(string part)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ApplicationUrl))
|
||||
|
|
|
@ -114,25 +114,13 @@ export interface ICustomizationSettings extends ISettings {
|
|||
applicationName: string;
|
||||
applicationUrl: string;
|
||||
logo: string;
|
||||
customCssLink: string;
|
||||
customCss: string;
|
||||
enableCustomDonations: boolean;
|
||||
customDonationUrl: string;
|
||||
customDonationMessage: string;
|
||||
hasPresetTheme: boolean;
|
||||
presetThemeName: string;
|
||||
presetThemeContent: string;
|
||||
presetThemeDisplayName: string;
|
||||
presetThemeVersion: string;
|
||||
recentlyAddedPage: boolean;
|
||||
}
|
||||
|
||||
export interface IThemes {
|
||||
fullName: string;
|
||||
displayName: string;
|
||||
version: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface IJobSettings {
|
||||
embyContentSync: string;
|
||||
sonarrSync: string;
|
||||
|
|
|
@ -31,7 +31,6 @@ import {
|
|||
ISlackNotificationSettings,
|
||||
ISonarrSettings,
|
||||
ITelegramNotifcationSettings,
|
||||
IThemes,
|
||||
IUpdateSettings,
|
||||
IUserManagementSettings,
|
||||
IVoteSettings,
|
||||
|
@ -135,14 +134,6 @@ export class SettingsService extends ServiceHelpers {
|
|||
return this.http.post<boolean>(`${this.url}/customization`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
|
||||
public getThemes(): Observable<IThemes[]> {
|
||||
return this.http.get<IThemes[]>(`${this.url}/themes`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public getThemeContent(themeUrl: string): Observable<string> {
|
||||
return this.http.get(`${this.url}/themecontent?url=${themeUrl}`, {responseType: "text", headers: this.headers});
|
||||
}
|
||||
|
||||
public getEmailNotificationSettings(): Observable<IEmailNotificationSettings> {
|
||||
return this.http.get<IEmailNotificationSettings>(`${this.url}/notifications/email`, {headers: this.headers});
|
||||
}
|
||||
|
|
|
@ -47,15 +47,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="customLink" class="control-label">Custom CSS Link</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="settings.customCssLink" class="form-control form-control-custom " name="customLink" value="{{settings.customCssLink}}"
|
||||
tooltipPosition="top" pTooltip="A link to a CSS file, you can use this to use your own styles for Ombi">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="enableCustomDonations" name="enableCustomDonations" [(ngModel)]="settings.enableCustomDonations">
|
||||
|
@ -63,7 +54,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-group" *ngIf="settings.enableCustomDonations">
|
||||
<label for="customDonation" class="control-label">Custom Donation URL</label>
|
||||
<div>
|
||||
<input [disabled]="!settings.enableCustomDonations" type="text" [(ngModel)]="settings.customDonationUrl" class="form-control form-control-custom " name="customDonation" value="{{settings.customDonationUrl}}"
|
||||
|
@ -71,7 +62,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-group" *ngIf="settings.enableCustomDonations">
|
||||
<label for="customDonationMessage" class="control-label">Donation Button Message</label>
|
||||
<div>
|
||||
<input [disabled]="!settings.enableCustomDonations" type="text" [(ngModel)]="settings.customDonationMessage" class="form-control form-control-custom " name="customDonationMessage" value="{{settings.customDonationMessage}}"
|
||||
|
@ -89,21 +80,15 @@
|
|||
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<div *ngIf="themes">
|
||||
<div>
|
||||
<div class="form-group">
|
||||
<label for="presetTheme" class="control-label">Preset Themes</label>
|
||||
<div id="presetTheme">
|
||||
<select class="form-control form-control-custom" (change)="dropDownChange($event)">
|
||||
<option *ngFor="let theme of themes" value="{{theme.fullName}}" [selected]="settings.presetThemeName === theme.fullName">{{theme.displayName}} {{theme.version}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<label for="customCss" class="control-label">Custom CSS</label>
|
||||
</div>
|
||||
<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 class="form-group language-css" pCode>
|
||||
<textarea rows="25" type="text"
|
||||
pTooltip="Enter your custom styles here" tooltipPosition="top"
|
||||
class="form-control-custom form-control " id="themeContent" name="themeContent" [(ngModel)]="settings.customCss"> {{settings.customCss}} </textarea>
|
||||
</div>
|
||||
<small>Preset themes are powered by
|
||||
<a href="https://github.com/leram84/layer.Cake" target="_blank">layer#Cake</a>.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
|
||||
import { ICustomizationSettings, IThemes } from "../../interfaces";
|
||||
import { ICustomizationSettings } from "../../interfaces";
|
||||
import { NotificationService } from "../../services";
|
||||
import { SettingsService } from "../../services";
|
||||
|
||||
|
@ -10,7 +10,6 @@ import { SettingsService } from "../../services";
|
|||
export class CustomizationComponent implements OnInit {
|
||||
|
||||
public settings: ICustomizationSettings;
|
||||
public themes: IThemes[];
|
||||
public advanced: boolean;
|
||||
|
||||
constructor(private settingsService: SettingsService, private notificationService: NotificationService) { }
|
||||
|
@ -18,26 +17,6 @@ export class CustomizationComponent implements OnInit {
|
|||
public ngOnInit() {
|
||||
this.settingsService.getCustomization().subscribe(x => {
|
||||
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: existingTheme.url, version: x.presetThemeVersion});
|
||||
this.themes.unshift({displayName: "None", fullName: "None", url: "", version: ""});
|
||||
} else {
|
||||
this.themes.unshift({displayName: "Please Select", fullName: "-1", url: "-1", version: ""});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -62,26 +41,4 @@ export class CustomizationComponent implements OnInit {
|
|||
});
|
||||
|
||||
}
|
||||
|
||||
public dropDownChange(event: any): void {
|
||||
const selectedThemeFullName = <string> event.target.value;
|
||||
const selectedTheme = this.themes.filter((val) => {
|
||||
return val.fullName === selectedThemeFullName;
|
||||
})[0];
|
||||
|
||||
if (selectedTheme.fullName === this.settings.presetThemeName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedTheme.fullName === "None" || selectedTheme.fullName === "-1") {
|
||||
this.settings.presetThemeName = "";
|
||||
this.settings.presetThemeContent = "";
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.presetThemeName = selectedThemeFullName;
|
||||
this.settingsService.getThemeContent(selectedTheme.url).subscribe(x => {
|
||||
this.settings.presetThemeContent = x;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,19 +274,6 @@ namespace Ombi.Controllers
|
|||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content of the theme available
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("themecontent")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> GetThemeContent([FromQuery]string url)
|
||||
{
|
||||
var css = await _githubApi.GetThemesRawContent(url);
|
||||
return Content(css, "text/css");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Sonarr Settings.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@using Ombi.Core.Settings
|
||||
@using Ombi.Helpers
|
||||
@using Ombi.Settings.Settings.Models
|
||||
@inject ISettingsService<OmbiSettings> Settings
|
||||
@inject ISettingsService<CustomizationSettings> CustomizationSettings
|
||||
|
@ -105,29 +106,12 @@
|
|||
</head>
|
||||
<body>
|
||||
@{
|
||||
if (customization.HasPresetTheme)
|
||||
if (customization.CustomCss.HasValue())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(baseUrl))
|
||||
{
|
||||
if (!customization.PresetThemeContent.Contains("/" + baseUrl))
|
||||
{
|
||||
var index = customization.PresetThemeContent.IndexOf("/api/");
|
||||
if (index > 0)
|
||||
{
|
||||
customization.PresetThemeContent = customization.PresetThemeContent.Insert(index, "/" + baseUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<style>
|
||||
@Html.Raw(customization.PresetThemeContent)
|
||||
<style>
|
||||
@Html.Raw(customization.CustomCss)
|
||||
</style>
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(customization.CustomCssLink))
|
||||
{
|
||||
<link rel="stylesheet" href="@customization.CustomCssLink" asp-append-version="true" />
|
||||
}
|
||||
}
|
||||
|
||||
@RenderBody()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue