* feat: add manual OAuth flow support in WebUI * fix: reset add account modal state on close * feat: display custom API key in startup banner * fix: move translations to separate files and optimize import API * fix: remove orphaned model-manager.js and cleanup callback server on manual auth --------- Co-authored-by: Badri Narayanan S <59133612+badrisnarayanan@users.noreply.github.com>
89 lines
3.0 KiB
JavaScript
89 lines
3.0 KiB
JavaScript
/**
|
|
* Add Account Modal Component
|
|
* Registers itself to window.Components for Alpine.js to consume
|
|
*/
|
|
window.Components = window.Components || {};
|
|
|
|
window.Components.addAccountModal = () => ({
|
|
manualMode: false,
|
|
authUrl: '',
|
|
authState: '',
|
|
callbackInput: '',
|
|
submitting: false,
|
|
|
|
/**
|
|
* Reset all state to initial values
|
|
*/
|
|
resetState() {
|
|
this.manualMode = false;
|
|
this.authUrl = '';
|
|
this.authState = '';
|
|
this.callbackInput = '';
|
|
this.submitting = false;
|
|
// Close any open details elements
|
|
const details = document.querySelectorAll('#add_account_modal details[open]');
|
|
details.forEach(d => d.removeAttribute('open'));
|
|
},
|
|
|
|
async copyLink() {
|
|
if (!this.authUrl) return;
|
|
await navigator.clipboard.writeText(this.authUrl);
|
|
Alpine.store('global').showToast(Alpine.store('global').t('linkCopied'), 'success');
|
|
},
|
|
|
|
async initManualAuth(event) {
|
|
if (event.target.open && !this.authUrl) {
|
|
try {
|
|
const password = Alpine.store('global').webuiPassword;
|
|
const {
|
|
response,
|
|
newPassword
|
|
} = await window.utils.request('/api/auth/url', {}, password);
|
|
if (newPassword) Alpine.store('global').webuiPassword = newPassword;
|
|
const data = await response.json();
|
|
if (data.status === 'ok') {
|
|
this.authUrl = data.url;
|
|
this.authState = data.state;
|
|
}
|
|
} catch (e) {
|
|
Alpine.store('global').showToast(e.message, 'error');
|
|
}
|
|
}
|
|
},
|
|
|
|
async completeManualAuth() {
|
|
if (!this.callbackInput || !this.authState) return;
|
|
this.submitting = true;
|
|
try {
|
|
const store = Alpine.store('global');
|
|
const {
|
|
response,
|
|
newPassword
|
|
} = await window.utils.request('/api/auth/complete', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
callbackInput: this.callbackInput,
|
|
state: this.authState
|
|
})
|
|
}, store.webuiPassword);
|
|
if (newPassword) store.webuiPassword = newPassword;
|
|
const data = await response.json();
|
|
if (data.status === 'ok') {
|
|
store.showToast(store.t('accountAddedSuccess'), 'success');
|
|
Alpine.store('data').fetchData();
|
|
document.getElementById('add_account_modal').close();
|
|
this.resetState();
|
|
} else {
|
|
store.showToast(data.error || store.t('authFailed'), 'error');
|
|
}
|
|
} catch (e) {
|
|
Alpine.store('global').showToast(e.message, 'error');
|
|
} finally {
|
|
this.submitting = false;
|
|
}
|
|
}
|
|
});
|