mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-26 05:24:09 -03:00
feat: support gated/private Hugging Face repos via access token
Add a huggingface_api_key setting (Settings UI, HF_TOKEN / HUGGING_FACE_HUB_TOKEN env override) and attach it as a Bearer token to Hugging Face file listing, model card fetching and downloads, so gated and private repositories can be downloaded once the user has accepted the repo terms. - fetch_json/fetch_text accept custom headers; ModelSource gains an auth_headers() hook so handlers stay platform-agnostic - 401/403 from the tree API now explain how to fix (configure token / accept gated terms) - aria2 pre-resolves huggingface.co redirects and strips credentials before handing the signed CDN URL to aria2, mirroring the CivitAI handling so the token never leaks to the CDN - settings API exposes huggingface_api_key_set only; the raw key joins _NO_SYNC_KEYS
This commit is contained in:
@@ -928,6 +928,7 @@ export class SettingsManager {
|
||||
|
||||
// Update API key status display (do NOT pre-fill the input)
|
||||
this.updateApiKeyStatus();
|
||||
this.updateHfApiKeyStatus();
|
||||
this.updateLlmApiKeyStatus();
|
||||
|
||||
// ── AI Provider settings ──────────────────────────────────────
|
||||
@@ -4350,6 +4351,28 @@ export class SettingsManager {
|
||||
}
|
||||
}
|
||||
|
||||
updateHfApiKeyStatus() {
|
||||
const hasKey = !!(state.global.settings.huggingface_api_key_set ||
|
||||
state.global.settings.huggingface_api_key);
|
||||
const statusText = document.getElementById('huggingfaceApiKeyStatusText');
|
||||
const actionBtn = document.getElementById('huggingfaceApiKeyActionBtn');
|
||||
if (!statusText || !actionBtn) return;
|
||||
|
||||
if (hasKey) {
|
||||
statusText.classList.remove('api-key-status--unconfigured');
|
||||
statusText.classList.add('api-key-status--configured');
|
||||
statusText.innerHTML = '<i class="fas fa-check-circle text-success"></i> '
|
||||
+ translate('settings.huggingfaceApiKeyConfigured', {}, 'Configured');
|
||||
actionBtn.textContent = translate('common.actions.change', {}, 'Change');
|
||||
} else {
|
||||
statusText.classList.remove('api-key-status--configured');
|
||||
statusText.classList.add('api-key-status--unconfigured');
|
||||
statusText.innerHTML = '<i class="fas fa-times-circle text-error"></i> '
|
||||
+ translate('settings.huggingfaceApiKeyNotConfigured', {}, 'Not configured');
|
||||
actionBtn.textContent = translate('settings.huggingfaceApiKeySet', {}, 'Set up');
|
||||
}
|
||||
}
|
||||
|
||||
updateLlmApiKeyStatus() {
|
||||
const hasKey = !!(state.global.settings.llm_api_key_set || state.global.settings.llm_api_key);
|
||||
const statusText = document.getElementById('llmApiKeyStatusText');
|
||||
@@ -4397,9 +4420,17 @@ export class SettingsManager {
|
||||
const input = document.getElementById(inputId);
|
||||
if (input) input.value = '';
|
||||
if (!silent) {
|
||||
if (inputId === 'civitaiApiKey') {
|
||||
this.updateApiKeyStatus();
|
||||
}
|
||||
this.refreshApiKeyStatus(inputId);
|
||||
}
|
||||
}
|
||||
|
||||
refreshApiKeyStatus(inputId) {
|
||||
if (inputId === 'civitaiApiKey') {
|
||||
this.updateApiKeyStatus();
|
||||
} else if (inputId === 'huggingfaceApiKey') {
|
||||
this.updateHfApiKeyStatus();
|
||||
} else if (inputId === 'llmApiKey') {
|
||||
this.updateLlmApiKeyStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4409,11 +4440,16 @@ export class SettingsManager {
|
||||
|
||||
const value = input.value.trim();
|
||||
|
||||
const labelNames = {
|
||||
civitai_api_key: 'CivitAI API Key',
|
||||
huggingface_api_key: 'Hugging Face Access Token',
|
||||
llm_api_key: 'LLM API Key',
|
||||
};
|
||||
|
||||
try {
|
||||
await this.saveSetting(settingsKey, value);
|
||||
const labelName = settingsKey === 'civitai_api_key' ? 'CivitAI API Key' : 'LLM API Key';
|
||||
showToast('toast.settings.settingsUpdated',
|
||||
{ setting: labelName }, 'success');
|
||||
{ setting: labelNames[settingsKey] || 'API Key' }, 'success');
|
||||
} catch (error) {
|
||||
showToast('toast.settings.settingSaveFailed',
|
||||
{ message: error.message }, 'error');
|
||||
@@ -4421,13 +4457,12 @@ export class SettingsManager {
|
||||
}
|
||||
|
||||
// Update the in-memory flag so the UI reflects the change
|
||||
if (settingsKey === 'civitai_api_key') {
|
||||
state.global.settings.civitai_api_key_set = !!value;
|
||||
const setFlagKey = `${settingsKey}_set`;
|
||||
if (setFlagKey in state.global.settings) {
|
||||
state.global.settings[setFlagKey] = !!value;
|
||||
}
|
||||
this.cancelEditApiKey(true, inputId);
|
||||
if (inputId === 'civitaiApiKey') {
|
||||
this.updateApiKeyStatus();
|
||||
}
|
||||
this.refreshApiKeyStatus(inputId);
|
||||
}
|
||||
|
||||
toggleInputVisibility(button) {
|
||||
|
||||
@@ -6,6 +6,8 @@ import { DEFAULT_PATH_TEMPLATES, DEFAULT_FILENAME_TEMPLATES, DEFAULT_PRIORITY_TA
|
||||
const DEFAULT_SETTINGS_BASE = Object.freeze({
|
||||
civitai_api_key: '',
|
||||
civitai_api_key_set: false,
|
||||
huggingface_api_key: '',
|
||||
huggingface_api_key_set: false,
|
||||
civitai_host: 'civitai.com',
|
||||
download_backend: 'python',
|
||||
aria2c_path: '',
|
||||
|
||||
Reference in New Issue
Block a user