Initial Ombi integration

When enabled, an account for the user is created on both Jellyfin and
Ombi. Account defaults can be stored similarly to jf.
This commit is contained in:
Harvey Tindall
2020-09-05 17:32:49 +01:00
parent 9850545f1b
commit ba67fa7536
11 changed files with 493 additions and 30 deletions
+51 -4
View File
@@ -9,6 +9,7 @@
"notifications",
"mailgun",
"smtp",
"ombi",
"files"
],
"jellyfin": {
@@ -62,7 +63,7 @@
"required": true,
"requires_restart": true,
"type": "text",
"value": "jf-accounts",
"value": "jfa-go",
"description": "This and below settings will show on the Jellyfin dashboard when the program connects. You may as well leave them alone."
},
"version": {
@@ -77,14 +78,14 @@
"required": true,
"requires_restart": true,
"type": "text",
"value": "jf-accounts"
"value": "jfa-go"
},
"device_id": {
"name": "Device ID",
"required": true,
"requires_restart": true,
"type": "text",
"value": "jf-accounts-{version}"
"value": "jfa-go-{version}"
}
},
"ui": {
@@ -466,7 +467,7 @@
"depends_true": "enabled",
"type": "text",
"value": "http://accounts.jellyf.in:8056/invite",
"description": "Base URL for jf-accounts. This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
"description": "Base URL for jfa-go. This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
}
},
"notifications": {
@@ -596,10 +597,48 @@
"value": "smtp password"
}
},
"ombi": {
"order": [
"enabled",
"server",
"api_key"
],
"meta": {
"name": "Ombi Integration",
"description": "Connect to Ombi to automatically create a new user's account. You'll need to create an Ombi user template."
},
"enabled": {
"name": "Enabled",
"required": false,
"requires_restart": true,
"type": "bool",
"value": false,
"description": "Enable to create an Ombi account for new Jellyfin users"
},
"server": {
"name": "URL",
"required": false,
"requires_restart": true,
"type": "text",
"value": "localhost:5000",
"depends_true": "enabled",
"description": "Ombi server URL."
},
"api_key": {
"name": "API Key",
"required": false,
"requires_restart": true,
"type": "text",
"value": "",
"depends_true": "enabled",
"description": "API Key. Get this from the first tab in Ombi settings."
}
},
"files": {
"order": [
"invites",
"emails",
"ombi_template",
"user_template",
"user_configuration",
"user_displayprefs",
@@ -625,6 +664,14 @@
"value": "",
"description": "Location of stored email addresses (json)."
},
"ombi_template": {
"name": "Ombi user template",
"required": false,
"requires_restart": false,
"type": "text",
"value": "",
"description": "Location of stored Ombi user template."
},
"user_template": {
"name": "User Template",
"required": false,
+103 -5
View File
@@ -627,9 +627,6 @@ document.getElementById('openDefaultsWizard').onclick = function() {
let users = req.response['users'];
let radioList = document.getElementById('defaultUserRadios');
radioList.textContent = '';
if (document.getElementById('setDefaultUser')) {
document.getElementById('setDefaultUser').remove();
}
let first = true;
for (user of users) {
let radio = document.createElement('div');
@@ -639,14 +636,14 @@ document.getElementById('openDefaultsWizard').onclick = function() {
first = false;
} else {
checked = '';
};
}
radio.innerHTML =
`<label><input type="radio" name="defaultRadios" id="default_${user['name']}" style="margin-right: 1rem;" ${checked}>${user['name']}</label>`;
radioList.appendChild(radio);
}
let button = document.getElementById('openDefaultsWizard');
button.disabled = false;
button.innerHTML = 'Set new account defaults';
button.innerHTML = 'New account defaults';
let submitButton = document.getElementById('storeDefaults');
submitButton.disabled = false;
submitButton.textContent = 'Submit';
@@ -715,6 +712,107 @@ document.getElementById('storeDefaults').onclick = function () {
}
};
var ombiDefaultsModal = '';
if (ombiEnabled) {
ombiDefaultsModal = createModal('ombiDefaults');
document.getElementById('openOmbiDefaults').onclick = function() {
this.disabled = true;
this.innerHTML =
'<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" style="margin-right: 0.5rem;"></span>' +
'Loading...';
let req = new XMLHttpRequest();
req.responseType = 'json';
req.open("GET", "/getOmbiUsers", true);
req.setRequestHeader("Authorization", "Basic " + btoa(window.token + ":"));
req.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
let users = req.response['users'];
let radioList = document.getElementById('ombiUserRadios');
radioList.textContent = '';
let first = true;
// name and id
for (user of users) {
let radio = document.createElement('div');
radio.classList.add('radio');
let checked = 'checked';
if (first) {
first = false;
} else {
checked = '';
}
radio.innerHTML =
`<label><input type="radio" name="ombiRadios" id="default_${user['id']}" style="margin-right: 1rem;" ${checked}>${user['name']}</label>`;
radioList.appendChild(radio);
}
let button = document.getElementById('openOmbiDefaults');
button.disabled = false;
button.innerHTML = 'Ombi user defaults';
let submitButton = document.getElementById('storeOmbiDefaults');
submitButton.disabled = false;
submitButton.textContent = 'Submit';
if (submitButton.classList.contains('btn-success')) {
submitButton.classList.remove('btn-success');
submitButton.classList.add('btn-primary');
} else if (submitButton.classList.contains('btn-danger')) {
submitButton.classList.remove('btn-danger');
submitButton.classList.add('btn-primary');
}
settingsModal.hide();
ombiDefaultsModal.show();
}
}
};
req.send();
};
document.getElementById('storeOmbiDefaults').onclick = function() {
this.disabled = true;
this.innerHTML =
'<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" style="margin-right: 0.5rem;"></span>' +
'Loading...';
let button = document.getElementById('storeOmbiDefaults');
let radios = document.getElementsByName('ombiRadios');
for (let radio of radios) {
if (radio.checked) {
let data = {
'id': radio.id.slice(8),
};
let req = new XMLHttpRequest();
req.open("POST", "/setOmbiDefaults", true);
req.setRequestHeader("Authorization", "Basic " + btoa(window.token + ":"));
req.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
req.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200 || this.status == 204) {
button.textContent = "Success";
if (button.classList.contains('btn-danger')) {
button.classList.remove('btn-danger');
} else if (button.classList.contains('btn-primary')) {
button.classList.remove('btn-primary');
}
button.classList.add('btn-success');
button.disabled = false;
setTimeout(function() { ombiDefaultsModal.hide(); }, 1000);
} else {
button.textContent = "Failed";
button.classList.remove('btn-primary');
button.classList.add('btn-danger');
setTimeout(function() {
let button = document.getElementById('storeOmbiDefaults');
button.textContent = "Submit";
button.classList.remove('btn-danger');
button.classList.add('btn-primary');
button.disabled = false;
}, 1000);
}
}
};
req.send(JSON.stringify(data));
}
}
};
}
document.getElementById('openUsers').onclick = function () {
this.disabled = true;
this.innerHTML =
+29
View File
@@ -52,6 +52,8 @@
}
css.setAttribute('href', cssFile);
document.head.appendChild(css);
// store whether ombi is enabled, 1 or 0.
var ombiEnabled = {{ .ombiEnabled }}
</script>
{{ if not .bs5 }}
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
@@ -177,6 +179,11 @@
<button type="button" class="list-group-item list-group-item-action" id="openDefaultsWizard">
New account defaults
</button>
{{ if .ombiEnabled }}
<button type="button" class="list-group-item list-group-item-action" id="openOmbiDefaults">
Ombi user defaults
</button>
{{ end }}
</ul>
<div class="list-group list-group-flush" id="settingsList">
</div>
@@ -230,6 +237,28 @@
</div>
</div>
</div>
{{ if .ombiEnabled }}
<div class="modal fade" id="ombiDefaults" role="dialog" aria-labelledby="Ombi Users" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="ombiTitle">Ombi user defaults</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Create an Ombi user and configure it to your liking, then choose it from below to store the settings and permissions as a template for all new users.</p>
<div id="ombiUserRadios"></div>
</div>
<div class="modal-footer" id="ombiFooter">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="storeOmbiDefaults">Submit</button>
</div>
</div>
</div>
</div>
{{ end }}
<div class="modal fade" id="restartModal" role="dialog" aria-labelledby="Restart Warning" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">