feat: make authentication optional — no tokens = no auth
Lint & Test / test (push) Successful in 10s
Lint & Test / test (push) Successful in 10s
When no api_tokens are configured (the new default), all endpoints are accessible without authentication. The frontend detects this via /api/health's auth_required field and skips the login form. - Backend: auth.py skips verification when api_tokens is empty - Frontend: shared getAuthHeaders()/hasCredentials() helpers replace scattered token logic across all JS modules - Health endpoint exposes auth_required for frontend discovery - config.example.yaml ships with tokens commented out - CLI --show-token and startup log reflect disabled state Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,19 +6,16 @@ import {
|
||||
t, showToast, escapeHtml, closeDialog, showConfirm,
|
||||
resolveMdiIcons, fetchMdiIcon,
|
||||
scripts, setScripts,
|
||||
getAuthHeaders, hasCredentials,
|
||||
} from './core.js';
|
||||
|
||||
export let scriptFormDirty = false;
|
||||
export function setScriptFormDirty(value) { scriptFormDirty = value; }
|
||||
|
||||
export async function loadScripts() {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/scripts/list', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
headers: getAuthHeaders()
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
@@ -67,10 +64,9 @@ export async function displayQuickAccess() {
|
||||
});
|
||||
|
||||
try {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
if (token) {
|
||||
if (hasCredentials()) {
|
||||
const response = await fetch('/api/links/list', {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
headers: getAuthHeaders()
|
||||
});
|
||||
if (gen !== _quickAccessGen) return;
|
||||
if (response.ok) {
|
||||
@@ -124,16 +120,12 @@ export async function displayQuickAccess() {
|
||||
}
|
||||
|
||||
async function executeScript(scriptName, buttonElement) {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
buttonElement.classList.add('executing');
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/scripts/execute/${scriptName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json', ...getAuthHeaders() },
|
||||
body: JSON.stringify({ args: [] })
|
||||
});
|
||||
|
||||
@@ -165,12 +157,11 @@ export async function loadScriptsTable() {
|
||||
}
|
||||
|
||||
async function _loadScriptsTableImpl() {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
const tbody = document.getElementById('scriptsTableBody');
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/scripts/list', {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
headers: getAuthHeaders()
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -232,13 +223,12 @@ export function showAddScriptDialog() {
|
||||
}
|
||||
|
||||
export async function showEditScriptDialog(scriptName) {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
const dialog = document.getElementById('scriptDialog');
|
||||
const title = document.getElementById('dialogTitle');
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/scripts/list', {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
headers: getAuthHeaders()
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -300,7 +290,6 @@ export async function saveScript(event) {
|
||||
const submitBtn = event.target.querySelector('button[type="submit"]');
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
const isEdit = document.getElementById('scriptIsEdit').value === 'true';
|
||||
const scriptName = isEdit ?
|
||||
document.getElementById('scriptOriginalName').value :
|
||||
@@ -324,10 +313,7 @@ export async function saveScript(event) {
|
||||
try {
|
||||
const response = await fetch(endpoint, {
|
||||
method,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json', ...getAuthHeaders() },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
@@ -353,14 +339,10 @@ export async function deleteScriptConfirm(scriptName) {
|
||||
return;
|
||||
}
|
||||
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/scripts/delete/${scriptName}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
headers: getAuthHeaders()
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
@@ -443,7 +425,6 @@ function showExecutionResult(name, result, type = 'script') {
|
||||
}
|
||||
|
||||
export async function executeScriptDebug(scriptName) {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
const dialog = document.getElementById('executionDialog');
|
||||
const title = document.getElementById('executionDialogTitle');
|
||||
const statusDiv = document.getElementById('executionStatus');
|
||||
@@ -463,10 +444,7 @@ export async function executeScriptDebug(scriptName) {
|
||||
try {
|
||||
const response = await fetch(`/api/scripts/execute/${scriptName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json', ...getAuthHeaders() },
|
||||
body: JSON.stringify({ args: [] })
|
||||
});
|
||||
|
||||
@@ -494,7 +472,6 @@ export async function executeScriptDebug(scriptName) {
|
||||
}
|
||||
|
||||
export async function executeCallbackDebug(callbackName) {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
const dialog = document.getElementById('executionDialog');
|
||||
const title = document.getElementById('executionDialogTitle');
|
||||
const statusDiv = document.getElementById('executionStatus');
|
||||
@@ -514,10 +491,7 @@ export async function executeCallbackDebug(callbackName) {
|
||||
try {
|
||||
const response = await fetch(`/api/callbacks/execute/${callbackName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
headers: { 'Content-Type': 'application/json', ...getAuthHeaders() }
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
Reference in New Issue
Block a user