Fix loading/saving JS Injector plugins

This commit is contained in:
HighImKevin committed 2026-03-04 14:34:24 -05:00
1 parent 36b288c9a0
commit 49d7a15b15
2 files changed
+53 -49

No files matched your search

+30 -14
View File
@@ -10,6 +10,22 @@
const MODAL_ID = 'kefinTweaksSourceModal'; const MODAL_ID = 'kefinTweaksSourceModal';
let versionsCache = null; let versionsCache = null;
function getAuthHeader() {
const token = ApiClient.accessToken();
const client = typeof ApiClient.applicationName === 'function' ? ApiClient.applicationName() : 'Jellyfin Web';
const device = typeof ApiClient.deviceName === 'function' ? ApiClient.deviceName() : (navigator.userAgent.includes('Chrome') ? 'Chrome' : 'Browser');
const deviceId = typeof ApiClient.deviceId === 'function' ? ApiClient.deviceId() : '';
const version = ApiClient._appVersion || ApiClient._serverVersion || '';
const parts = [
`Client="${encodeURIComponent(client)}"`,
`Device="${encodeURIComponent(device)}"`,
`DeviceId="${encodeURIComponent(deviceId)}"`,
`Version="${encodeURIComponent(version)}"`,
`Token="${encodeURIComponent(token)}"`
];
return `MediaBrowser ${parts.join(', ')}`;
}
// jsDelivr URL patterns // jsDelivr URL patterns
const JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/ranaldsgift/KefinTweaks'; const JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/ranaldsgift/KefinTweaks';
const GITHUB_REPO = 'ranaldsgift/KefinTweaks'; const GITHUB_REPO = 'ranaldsgift/KefinTweaks';
@@ -31,16 +47,15 @@
// Find JavaScript Injector plugin // Find JavaScript Injector plugin
async function findJavaScriptInjectorPlugin() { async function findJavaScriptInjectorPlugin() {
try { try {
if (!window.ApiClient || !window.ApiClient._serverAddress || !window.ApiClient.accessToken) { if (!window.ApiClient || !window.ApiClient._serverAddress || window.ApiClient.accessToken() === null) {
return null; return null;
} }
const server = ApiClient._serverAddress; const server = ApiClient._serverAddress;
const token = ApiClient.accessToken();
const response = await fetch(`${server}/Plugins`, { const response = await fetch(`${server}/Plugins`, {
headers: { headers: {
'X-Emby-Token': token 'Authorization': getAuthHeader()
} }
}); });
@@ -74,11 +89,10 @@
} }
const server = ApiClient._serverAddress; const server = ApiClient._serverAddress;
const token = ApiClient.accessToken();
const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, { const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, {
headers: { headers: {
'X-Emby-Token': token 'Authorization': getAuthHeader()
} }
}); });
@@ -198,12 +212,11 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
} }
const server = ApiClient._serverAddress; const server = ApiClient._serverAddress;
const token = ApiClient.accessToken();
const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, { const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, {
method: 'POST', method: 'POST',
headers: { headers: {
'X-Emby-Token': token, 'Authorization': getAuthHeader(),
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(injectorConfig) body: JSON.stringify(injectorConfig)
@@ -877,12 +890,11 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
// Save the updated configuration // Save the updated configuration
const server = ApiClient._serverAddress; const server = ApiClient._serverAddress;
const token = ApiClient.accessToken();
const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, { const response = await fetch(`${server}/Plugins/${pluginId}/Configuration`, {
method: 'POST', method: 'POST',
headers: { headers: {
'X-Emby-Token': token, 'Authorization': getAuthHeader(),
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(injectorConfig) body: JSON.stringify(injectorConfig)
@@ -1315,6 +1327,7 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
if (hash && hash.includes('dashboard/plugins')) { if (hash && hash.includes('dashboard/plugins')) {
const pluginsPage = document.querySelector('#pluginsPage:not(.hide)'); const pluginsPage = document.querySelector('#pluginsPage:not(.hide)');
if (!pluginsPage) { if (!pluginsPage) {
console.log('[KefinTweaks Installer] Plugins page not found');
return; return;
} }
@@ -1325,12 +1338,15 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
installedPlugins = document.querySelector('#pluginsPage:not(.hide)>div>div>div:last-child>div'); installedPlugins = document.querySelector('#pluginsPage:not(.hide)>div>div>div:last-child>div');
} }
if (pluginsPage && installedPlugins) { if (!installedPlugins || !pluginsPage) {
// Small delay to ensure DOM is ready console.log('[KefinTweaks Installer] Installed plugins or plugins page not found');
setTimeout(() => { return;
addKefinTweaksPluginCard(installedPlugins);
}, 100);
} }
// Small delay to ensure DOM is ready
setTimeout(() => {
addKefinTweaksPluginCard(installedPlugins);
}, 100);
} }
} }
+23 -35
View File
@@ -51,6 +51,26 @@
} }
} }
/**
* Build MediaBrowser Authorization header
* @returns {string} - Authorization header
*/
function getAuthHeader() {
const token = ApiClient.accessToken();
const client = typeof ApiClient.applicationName === 'function' ? ApiClient.applicationName() : 'Jellyfin Web';
const device = typeof ApiClient.deviceName === 'function' ? ApiClient.deviceName() : (navigator.userAgent.includes('Chrome') ? 'Chrome' : 'Browser');
const deviceId = typeof ApiClient.deviceId === 'function' ? ApiClient.deviceId() : '';
const version = ApiClient._appVersion || ApiClient._serverVersion || '';
const parts = [
`Client="${encodeURIComponent(client)}"`,
`Device="${encodeURIComponent(device)}"`,
`DeviceId="${encodeURIComponent(deviceId)}"`,
`Version="${encodeURIComponent(version)}"`,
`Token="${encodeURIComponent(token)}"`
];
return `MediaBrowser ${parts.join(', ')}`;
}
// Array to store registered handlers // Array to store registered handlers
const handlers = []; const handlers = [];
@@ -417,39 +437,7 @@
throw new Error('No config provided and window.KefinTweaksConfig is not available'); throw new Error('No config provided and window.KefinTweaksConfig is not available');
} }
// Find JavaScript Injector plugin const pluginsData = await apiHelper.getPlugins();
const server = window.ApiClient.serverAddress();
const token = window.ApiClient.accessToken();
if (!server || !token) {
throw new Error('Server address or access token not available');
}
let pluginsResponse = await fetch(`${server}/Plugins`, {
headers: { 'X-Emby-Token': token }
});
// Handle 401 Unauthorized - retry once after waiting if waitForLogin is enabled
if (pluginsResponse.status === 401 && shouldWaitForLogin) {
WARN('Received 401 Unauthorized, waiting for login and retrying...');
const loggedIn = await waitForLogin(5000); // Wait up to 5 more seconds
if (loggedIn) {
// Retry with fresh token
const freshToken = window.ApiClient.accessToken();
pluginsResponse = await fetch(`${server}/Plugins`, {
headers: { 'X-Emby-Token': freshToken }
});
}
}
if (!pluginsResponse.ok) {
if (pluginsResponse.status === 401) {
throw new Error('Unauthorized - user may not be logged in or session expired');
}
throw new Error(`Failed to get plugins: ${pluginsResponse.status} ${pluginsResponse.statusText}`);
}
const pluginsData = await pluginsResponse.json();
const pluginsList = Array.isArray(pluginsData) ? pluginsData : (pluginsData.Items || []); const pluginsList = Array.isArray(pluginsData) ? pluginsData : (pluginsData.Items || []);
const plugin = pluginsList.find(p => p.Name === 'JavaScript Injector' || p.Name === 'JS Injector'); const plugin = pluginsList.find(p => p.Name === 'JavaScript Injector' || p.Name === 'JS Injector');
@@ -463,7 +451,7 @@
// Get current injector config // Get current injector config
const configUrl = `${server}/Plugins/${pluginId}/Configuration`; const configUrl = `${server}/Plugins/${pluginId}/Configuration`;
const configResponse = await fetch(configUrl, { const configResponse = await fetch(configUrl, {
headers: { 'X-Emby-Token': token } headers: { 'Authorization': getAuthHeader() }
}); });
if (!configResponse.ok) { if (!configResponse.ok) {
@@ -506,7 +494,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToSave, null, 2)};`;
const saveResponse = await fetch(configUrl, { const saveResponse = await fetch(configUrl, {
method: 'POST', method: 'POST',
headers: { headers: {
'X-Emby-Token': token, 'Authorization': getAuthHeader(),
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(injectorConfig) body: JSON.stringify(injectorConfig)