Commit 0be687ce authored by echel0n's avatar echel0n
Browse files

Merge branch 'release/10.0.49'

parents fac83cc2 ca312990
......@@ -2,8 +2,12 @@
 
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
 
#### [10.0.49](https://git.sickrage.ca/SiCKRAGE/sickrage/compare/10.0.48...10.0.49)
#### [10.0.48](https://git.sickrage.ca/SiCKRAGE/sickrage/compare/10.0.47...10.0.48)
 
> 22 January 2022
#### [10.0.47](https://git.sickrage.ca/SiCKRAGE/sickrage/compare/10.0.46...10.0.47)
 
> 1 January 2022
......
{
"name": "sickrage",
"version": "10.0.48",
"version": "10.0.49",
"private": true,
"repository": {
"type": "git",
......
[bumpversion]
current_version = 10.0.48
current_version = 10.0.49
commit = False
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<dev>\d+))?
......
......@@ -19,7 +19,7 @@
# along with SiCKRAGE. If not, see <http://www.gnu.org/licenses/>.
# ##############################################################################
__version__ = "10.0.48"
__version__ = "10.0.49"
__install_type__ = ""
import argparse
......
sickrage/checksums.md5 = d41d8cd98f00b204e9800998ecf8427e
sickrage/__init__.py = 13f349c1f07b79bf225e5048e12664ac
sickrage/version.txt = 5778e96d420b93f665cdb5c967cf9b3b
sickrage/__init__.py = 2d6ac67b5908d1ad4ceb62b033b6886a
sickrage/version.txt = e396edc88a7a9446b0166e05a3f3865a
sickrage/clients/__init__.py = abafc862109398700c9fee676cdeef6b
sickrage/clients/nzb/nzbget.py = 2a23083d4915fed22c73f4966588cac8
sickrage/clients/nzb/sabnzbd.py = f76666e47017abaf366f4a3e8b71c47b
......@@ -208,7 +208,7 @@ sickrage/notification_providers/__init__.py = 566ab4ebcd356e4384cdf75e6f0aa375
sickrage/notification_providers/nmj.py = 16b1b008aa8200c0ad3eb065b6137b4b
sickrage/notification_providers/synology.py = bdb3f339ae68cdae4a20c69a2515d641
sickrage/core/classes.py = ca0d7c07b684b8fe22788346dc755fd8
sickrage/core/version_updater.py = 5ca6ed7001d796a1f1e27be18522c840
sickrage/core/version_updater.py = 36ed1e3b7ae29c7e719b487d70ef1003
sickrage/core/traktapi.py = e30a23461b7e5d3af7619ad3e229bc40
sickrage/core/announcements.py = 6c3ed44e7ae50c281383ab5f278102c6
sickrage/core/enums.py = 5a8fac089e8c4451a1d6b28c1762e684
......@@ -221,7 +221,7 @@ sickrage/core/upnp.py = 51eb609bd1f59baa3c0c346d5ac19787
sickrage/core/nzbSplitter.py = 8bb813262916d2208e905fb53e575284
sickrage/core/search.py = bcb6d5972f5808d7ab9570a8a39b2d02
sickrage/core/scene_numbering.py = e517e5232d3b9ca186fe8b33578abd4b
sickrage/core/__init__.py = 8251e573ba25be4105a7a27d0669ae34
sickrage/core/__init__.py = cd371888e58e5b6015fc0b8465cd9217
sickrage/core/common.py = 8eca84658272c806858b105179285693
sickrage/core/queues/show.py = 103dd378a6b9d3a412ea50e239aee5cb
sickrage/core/queues/postprocessor.py = b2bcd7642060906c2c21d554d114b9ee
......@@ -252,7 +252,7 @@ sickrage/core/helpers/compat.py = 13a5ce81a9ef355d983d0803c282339d
sickrage/core/helpers/encryption.py = 8a74f080644fcfe249e56e8a31c2f62e
sickrage/core/helpers/srdatetime.py = 1ec93b21792f45dbcd8a574c02db4d34
sickrage/core/helpers/browser.py = 6da2ce70dea2674b01543ad1a4f216b2
sickrage/core/helpers/__init__.py = 07f621313c0c91b72ca9756703655534
sickrage/core/helpers/__init__.py = bcb295a25ce3f3d1f676a0e00a351512
sickrage/core/logger/__init__.py = 1d7a61b5c2a9465ec9f947adb4d0e9d1
sickrage/core/updaters/show_updater.py = 8f5649d5b83c69876a61f8b0dd966abc
sickrage/core/updaters/tz_updater.py = 45ce45d6e44e5b8ab28bda9520200514
......@@ -330,7 +330,8 @@ sickrage/core/config/helpers.py = 8d0d9e502b0fa5eff071558ca0f496d3
sickrage/core/config/__init__.py = 46b90c5683b8e547f63b69f8a612e27a
sickrage/core/amqp/consumer.py = 8c7d9aaf2f084c41c7fb1b35394adbed
sickrage/core/amqp/__init__.py = d64bec8a41b2f2d393b309eb2f33f5f0
sickrage/core/webserver/__init__.py = b56927ec9027045d1656f9a55344a09e
sickrage/core/webserver/helpers.py = d769dcf63a6215ea549e19100b427f21
sickrage/core/webserver/__init__.py = 5b80abd646e44b6160aabbe03c058dfe
sickrage/core/webserver/handlers/announcements.py = cca0415f047c367e5b41c0fed6a24dbf
sickrage/core/webserver/handlers/web_file_browser.py = fd7ea59001053b333cd56960181d4550
sickrage/core/webserver/handlers/logout.py = b91b1805bfd1ba69e8d19dc3254f5708
......@@ -376,7 +377,7 @@ sickrage/core/webserver/handlers/config/notifications.py = 88ee26540e55fa1aa65de
sickrage/core/webserver/handlers/config/search.py = 6ced2a39316938481d9d5086184bb3c5
sickrage/core/webserver/handlers/config/providers.py = be107f3d5505a36e01feb7854fac919b
sickrage/core/webserver/handlers/config/__init__.py = 1b9eeca6d49289e7c36bf369450e459c
sickrage/core/webserver/handlers/config/general.py = dd818e0eb542187a4d676a8e7c0b0f97
sickrage/core/webserver/handlers/config/general.py = 35e6cb4543ba37722f24f04e6835ec89
sickrage/core/webserver/handlers/home/add_shows.py = f804dd91bfff99cc079f14f83e2604f3
sickrage/core/webserver/handlers/home/postprocess.py = bd1ea821bd162300af4b5bf27c5aba94
sickrage/core/webserver/handlers/home/__init__.py = e9cd242d928a6881fce94adb3e542974
......@@ -429,7 +430,7 @@ sickrage/core/webserver/static/images/backdrops/config.jpg = ddbe8915317f7860d91
sickrage/core/webserver/static/images/backdrops/home.jpg = 804dfc976638bbf45df310a3627e2d5c
sickrage/core/webserver/static/images/backdrops/schedule.jpg = 0c0e5f4dcee42bfcfb73de100f1d3015
sickrage/core/webserver/static/images/backdrops/history.jpg = b4911bfe3ec57a894b5a16fa1ab479cf
sickrage/core/webserver/static/js/core.min.js = 5d1e5c62a384354fc16be794af1c8cc1
sickrage/core/webserver/static/js/core.min.js = 3fc744708a640ba7a21e678e91040eea
sickrage/core/webserver/static/js/core.js.map = cdf19c1422438fb68dd84471031b2c56
sickrage/core/webserver/views/login.mako = 3f6c8e8325928539d6bb70a77b378116
sickrage/core/webserver/views/login_failed.mako = 5684d10edff37970a2285d7d5bb815eb
......@@ -466,7 +467,7 @@ sickrage/core/webserver/views/config/providers.mako = 3369219afcaa0b9be51e7f1737
sickrage/core/webserver/views/config/backup_restore.mako = fceae0a471cb0df3477f24f8d35de574
sickrage/core/webserver/views/config/quality_settings.mako = c4fd4793b475aa8aafdaac0444390a43
sickrage/core/webserver/views/config/search.mako = 3d2c6d0f8b771cb67f3c8967d333c432
sickrage/core/webserver/views/config/general.mako = b78a4c9434768901b6a6d67fc41e80f7
sickrage/core/webserver/views/config/general.mako = 2bd1c41f1251f26e61f092239b694fab
sickrage/core/webserver/views/home/edit_show.mako = d523e7a405adcaee43cf77609c552af2
sickrage/core/webserver/views/home/trakt_shows.mako = 09a95e4badea76e427946773a6cfa650
sickrage/core/webserver/views/home/server_status.mako = 35c73890074a64a60f2c761d9503a138
......
......@@ -98,9 +98,6 @@ class Core(object):
self.gui_views_dir = os.path.join(sickrage.PROG_DIR, 'core', 'webserver', 'views')
self.gui_app_dir = os.path.join(sickrage.PROG_DIR, 'core', 'webserver', 'app')
self.https_cert_file = None
self.https_key_file = None
self.trakt_api_key = '5c65f55e11d48c35385d9e8670615763a605fad28374c8ae553a7b7a50651ddd'
self.trakt_api_secret = 'b53e32045ac122a445ef163e6d859403301ffe9b17fb8321d428531b69022a82'
self.trakt_app_id = '4562'
......@@ -342,10 +339,6 @@ class Core(object):
# set socket timeout
socket.setdefaulttimeout(self.config.general.socket_timeout)
# set ssl cert/key filenames
self.https_cert_file = os.path.abspath(os.path.join(self.data_dir, 'server.crt'))
self.https_key_file = os.path.abspath(os.path.join(self.data_dir, 'server.key'))
# setup logger settings
self.log.logSize = self.config.general.log_size
self.log.logNr = self.config.general.log_nr
......
......@@ -50,11 +50,6 @@ import errno
import rarfile
import requests
from bs4 import BeautifulSoup
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
import sickrage
from sickrage.core.enums import TorrentMethod
......@@ -760,53 +755,6 @@ def sanitize_scene_name(name, anime=False):
return name
def create_https_certificates(ssl_cert, ssl_key):
"""This function takes a domain name as a parameter and then creates a certificate and key with the
domain name(replacing dots by underscores), finally signing the certificate using specified CA and
returns the path of key and cert files. If you are yet to generate a CA then check the top comments"""
# Generate our key
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend(),
)
name = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, 'SiCKRAGE')
])
# path_len=0 means this cert can only sign itself, not other certs.
basic_contraints = x509.BasicConstraints(ca=True, path_length=0)
now = datetime.datetime.utcnow()
cert = (
x509.CertificateBuilder()
.subject_name(name)
.issuer_name(name)
.public_key(key.public_key())
.serial_number(1000)
.not_valid_before(now)
.not_valid_after(now + datetime.timedelta(days=10 * 365))
.add_extension(basic_contraints, False)
# .add_extension(san, False)
.sign(key, hashes.SHA256(), default_backend())
)
cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)
key_pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
with open(ssl_key, 'wb') as key_out:
key_out.write(key_pem)
with open(ssl_cert, 'wb') as cert_out:
cert_out.write(cert_pem)
return True
def anon_url(*url):
"""
Return a URL string consisting of the Anonymous redirect URL and an arbitrary number of values appended.
......
......@@ -18,6 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with SiCKRAGE. If not, see <http://www.gnu.org/licenses/>.
# ##############################################################################
import configparser
import os
import platform
import re
......@@ -256,7 +257,8 @@ class UpdateManager(object):
if not self.manual_update:
update_url = f"{sickrage.app.config.general.web_root}/home/update/?pid={sickrage.app.pid}"
message = _(f'New SiCKRAGE {self.current_branch} {sickrage.install_type()} update available, version {latest_version} &mdash; <a href=\"{update_url}\">Update Now</a>')
message = _(
f'New SiCKRAGE {self.current_branch} {sickrage.install_type()} update available, version {latest_version} &mdash; <a href=\"{update_url}\">Update Now</a>')
else:
message = _(f"New SiCKRAGE {self.current_branch} {sickrage.install_type()} update available, version {latest_version}, please manually update!")
......@@ -595,6 +597,18 @@ class WindowsUpdateManager(UpdateManager):
self.type = "windows"
self.manual_update = True
@property
def latest_version(self):
latest_version = None
try:
version_url = "https://www.sickrage.ca/downloads/windows/updates.txt"
version_config = configparser.ConfigParser()
version_config.read_string(WebSession().get(version_url).text)
latest_version = version_config['SiCKRAGE']['Version'].rsplit('.', 1)[0]
finally:
return latest_version or self.version
class SynologyUpdateManager(UpdateManager):
def __init__(self):
......
......@@ -26,16 +26,13 @@ import ssl
import tornado.autoreload
import tornado.locale
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.x509 import ExtensionNotFound
from mako.lookup import TemplateLookup
from tornado.httpserver import HTTPServer
from tornado.ioloop import PeriodicCallback, IOLoop
from tornado.ioloop import IOLoop
from tornado.web import Application, RedirectHandler, StaticFileHandler
import sickrage
from sickrage.core.helpers import create_https_certificates
from sickrage.core.webserver.helpers import create_https_certificates, is_certificate_valid, certificate_needs_renewal
from sickrage.core.webserver.handlers.account import AccountLinkHandler, AccountUnlinkHandler, AccountIsLinkedHandler
from sickrage.core.webserver.handlers.announcements import AnnouncementsHandler, MarkAnnouncementSeenHandler, AnnouncementCountHandler
from sickrage.core.webserver.handlers.api import ApiSwaggerDotJsonHandler, ApiPingHandler, ApiProfileHandler
......@@ -136,6 +133,18 @@ class WebServer(object):
self.app = None
self.server = None
@property
def cert_file(self):
if os.path.exists(sickrage.app.config.general.https_cert):
return sickrage.app.config.general.https_cert
return os.path.abspath(os.path.join(sickrage.app.data_dir, 'server.crt'))
@property
def cert_key_file(self):
if os.path.exists(sickrage.app.config.general.https_key):
return sickrage.app.config.general.https_key
return os.path.abspath(os.path.join(sickrage.app.data_dir, 'server.key'))
def start(self):
self.started = True
......@@ -167,7 +176,7 @@ class WebServer(object):
# tornado SSL setup
if sickrage.app.config.general.enable_https:
if not self.load_ssl_certificate():
sickrage.app.log.info("Unable to retrieve CERT/KEY files from SiCKRAGE API, disabling HTTPS")
sickrage.app.log.info("Unable to load HTTPS certificate and key files, disabling HTTPS")
sickrage.app.config.general.enable_https = False
# Load templates
......@@ -482,7 +491,7 @@ class WebServer(object):
ssl_ctx = None
if sickrage.app.config.general.enable_https:
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(sickrage.app.https_cert_file, sickrage.app.https_key_file)
ssl_ctx.load_cert_chain(self.cert_file, self.cert_key_file)
# Web Server
self.server = HTTPServer(self.app, ssl_options=ssl_ctx, xheaders=sickrage.app.config.general.handle_reverse_proxy)
......@@ -494,31 +503,41 @@ class WebServer(object):
raise SystemExit
def load_ssl_certificate(self, certificate=None, private_key=None):
sr_cert_file = os.path.abspath(os.path.join(sickrage.app.data_dir, 'server.crt'))
sr_cert_key_file = os.path.abspath(os.path.join(sickrage.app.data_dir, 'server.key'))
# Custom user provided HTTPS certificate and certificate key files
if os.path.exists(sickrage.app.config.general.https_cert) and os.path.exists(sickrage.app.config.general.https_key):
if certificate_needs_renewal(sickrage.app.config.general.https_cert):
return False
return True
# SiCKRAGE HTTPS certificate and certificate key files
if certificate and private_key:
with open(sickrage.app.https_cert_file, 'w') as cert_out:
with open(sr_cert_file, 'w') as cert_out:
cert_out.write(certificate)
with open(sickrage.app.https_key_file, 'w') as key_out:
with open(sr_cert_key_file, 'w') as key_out:
key_out.write(private_key)
else:
if os.path.exists(sickrage.app.https_key_file) and os.path.exists(sickrage.app.https_cert_file):
if self.is_certificate_valid() and not self.certificate_needs_renewal():
if os.path.exists(sr_cert_file) and os.path.exists(sr_cert_key_file):
if is_certificate_valid(sr_cert_file) and not certificate_needs_renewal(sr_cert_file):
return True
resp = sickrage.app.api.server.get_server_certificate(sickrage.app.config.general.server_id)
if not resp or 'certificate' not in resp or 'private_key' not in resp:
if not create_https_certificates(sickrage.app.https_cert_file, sickrage.app.https_key_file):
if not create_https_certificates(sr_cert_file, sr_cert_key_file):
return False
if not os.path.exists(sickrage.app.https_cert_file) or not os.path.exists(sickrage.app.https_key_file):
if not os.path.exists(sr_cert_file) or not os.path.exists(sr_cert_key_file):
return False
return True
with open(sickrage.app.https_cert_file, 'w') as cert_out:
with open(sr_cert_file, 'w') as cert_out:
cert_out.write(resp['certificate'])
with open(sickrage.app.https_key_file, 'w') as key_out:
with open(sr_cert_key_file, 'w') as key_out:
key_out.write(resp['private_key'])
sickrage.app.log.info("Loaded SSL certificate successfully, restarting server in 1 minute")
......@@ -529,52 +548,6 @@ class WebServer(object):
return True
def certificate_needs_renewal(self):
if not os.path.exists(sickrage.app.https_cert_file):
return
with open(sickrage.app.https_cert_file, 'rb') as f:
cert_pem = f.read()
cert = x509.load_pem_x509_certificate(cert_pem, default_backend())
not_valid_after = cert.not_valid_after
return not_valid_after - datetime.datetime.utcnow() < (cert.not_valid_after - cert.not_valid_before) / 2
def is_certificate_valid(self):
if not os.path.exists(sickrage.app.https_cert_file):
return
with open(sickrage.app.https_cert_file, 'rb') as f:
cert_pem = f.read()
cert = x509.load_pem_x509_certificate(cert_pem, default_backend())
issuer = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME)[0]
subject = cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)[0]
if 'ZeroSSL' not in issuer.value:
return False
if subject.value != f'{sickrage.app.config.general.server_id}.external.sickrage.direct':
return False
try:
ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value
sans = ext.get_values_for_type(x509.DNSName)
domains = [
f'{sickrage.app.config.general.server_id}.external.sickrage.direct',
f'{sickrage.app.config.general.server_id}.internal.sickrage.direct'
]
for domain in sans:
if domain not in domains:
return False
except ExtensionNotFound:
return False
return True
def shutdown(self):
if self.started:
self.started = False
......
......@@ -18,6 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with SiCKRAGE. If not, see <http://www.gnu.org/licenses/>.
# ##############################################################################
import os
from tornado.web import authenticated
......@@ -256,11 +257,11 @@ class SaveGeneralHandler(BaseHandler):
sickrage.app.config.general.enable_https = checkbox_to_value(enable_https)
# if not change_https_cert(https_cert):
# results += ["Unable to create directory " + os.path.normpath(https_cert) + ", https cert directory not changed."]
#
# if not change_https_key(https_key):
# results += ["Unable to create directory " + os.path.normpath(https_key) + ", https key directory not changed."]
if os.path.exists(https_cert):
sickrage.app.config.general.https_cert = https_cert
if os.path.exists(https_key):
sickrage.app.config.general.https_key = https_key
sickrage.app.config.general.handle_reverse_proxy = checkbox_to_value(handle_reverse_proxy)
......
import datetime
import os
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509 import ExtensionNotFound
from cryptography.x509.oid import NameOID
import sickrage
def create_https_certificates(ssl_cert, ssl_key):
"""This function takes a domain name as a parameter and then creates a certificate and key with the
domain name(replacing dots by underscores), finally signing the certificate using specified CA and
returns the path of key and cert files. If you are yet to generate a CA then check the top comments"""
# Generate our key
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend(),
)
name = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, 'SiCKRAGE')
])
# path_len=0 means this cert can only sign itself, not other certs.
basic_contraints = x509.BasicConstraints(ca=True, path_length=0)
now = datetime.datetime.utcnow()
cert = (
x509.CertificateBuilder()
.subject_name(name)
.issuer_name(name)
.public_key(key.public_key())
.serial_number(1000)
.not_valid_before(now)
.not_valid_after(now + datetime.timedelta(days=10 * 365))
.add_extension(basic_contraints, False)
# .add_extension(san, False)
.sign(key, hashes.SHA256(), default_backend())
)
cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)
key_pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
with open(ssl_key, 'wb') as key_out:
key_out.write(key_pem)
with open(ssl_cert, 'wb') as cert_out:
cert_out.write(cert_pem)
return True
def is_certificate_valid(cert_file):
if not os.path.exists(cert_file):
return
with open(cert_file, 'rb') as f:
cert_pem = f.read()
cert = x509.load_pem_x509_certificate(cert_pem, default_backend())
issuer = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME)[0]
subject = cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)[0]
if 'ZeroSSL' not in issuer.value:
return False
if subject.value != f'{sickrage.app.config.general.server_id}.external.sickrage.direct':
return False
try:
ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value
sans = ext.get_values_for_type(x509.DNSName)
domains = [
f'{sickrage.app.config.general.server_id}.external.sickrage.direct',
f'{sickrage.app.config.general.server_id}.internal.sickrage.direct'
]
for domain in sans:
if domain not in domains:
return False
except ExtensionNotFound:
return False
return True
def certificate_needs_renewal(cert_file):
if not os.path.exists(cert_file):
return
with open(cert_file, 'rb') as f:
cert_pem = f.read()
cert = x509.load_pem_x509_certificate(cert_pem, default_backend())
not_valid_after = cert.not_valid_after
return not_valid_after - datetime.datetime.utcnow() < (cert.not_valid_after - cert.not_valid_before) / 2
\ No newline at end of file
......@@ -81729,7 +81729,7 @@ var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
if (isUndefined(debugEnviron))
debugEnviron = Object({"SENTRY_DSN":'https://[email protected]/2',"PACKAGE_VERSION":"10.0.48"}).NODE_DEBUG || '';
debugEnviron = Object({"SENTRY_DSN":'https://[email protected]/2',"PACKAGE_VERSION":"10.0.49"}).NODE_DEBUG || '';
set = set.toUpperCase();
if (!debugs[set]) {
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
......@@ -82538,7 +82538,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
 
Sentry.init({
dsn: 'https://[email protected]/2',
release: "10.0.48",
release: "10.0.49",
beforeSend: function beforeSend(event, hint) {
if (event.exception) {
event.exception.values[0].stacktrace.frames.forEach(function (frame) {
......@@ -957,51 +957,51 @@ c<%inherit file="../layouts/config.mako"/>
</div>
</div>
## <div id="content_enable_https">
## <div class="form-row form-group">
##
## <div class="col-lg-3 col-md-4 col-sm-5">
## <label class="component-title">${_('HTTPS certificate')}</label>
## </div>
## <div class="col-lg-9 col-md-8 col-sm-7 component-desc">
## <div class="form-row">
## <div class="col-md-12">
## <input name="https_cert" id="https_cert"
## value="${sickrage.app.config.general.https_cert}"
## class="form-control"
## autocapitalize="off"/>
## </div>
## </div>
## <div class="form-row">
## <div class="col-md-12">
## <label for="https_cert">
## ${_('file name or path to HTTPS certificate')}
## </label>
## </div>
## </div>
## </div>
## </div>
##
## <div class="form-row form-group">
## <div class="col-lg-3 col-md-4 col-sm-5">
## <label class="component-title">${_('HTTPS key')}</label>
## </div>
## <div class="col-lg-9 col-md-8 col-sm-7 component-desc">
## <div class="form-row">
## <div class="col-md-12">
## <input name="https_key" id="https_key"
## value="${sickrage.app.config.general.https_key}"
## class="form-control" autocapitalize="off"/>
## </div>
## </div>
## <div class="form-row">
## <div class="col-md-12">
## <label for="https_key">${_('file name or path to HTTPS key')}</label>
## </div>
## </div>
## </div>
## </div>
## </div>
<div id="content_enable_https">
<div class="form-row form-group">
<div class="col-lg-3 col-md-4 col-sm-5">
<label class="component-title">${_('Custom HTTPS certificate')}</label>
</div>
<div class="col-lg-9 col-md-8 col-sm-7 component-desc">
<div class="form-row">
<div class="col-md-12">
<input name="https_cert" id="https_cert"
value="${sickrage.app.config.general.https_cert}"
class="form-control"
autocapitalize="off"/>
</div>