#803 Add a separate field for proxy password

This commit is contained in:
Cohee 2023-07-28 21:33:29 +03:00
parent 707ce62017
commit 3fb4756c03
4 changed files with 42 additions and 64 deletions

View File

@ -545,6 +545,19 @@
<input id="openai_reverse_proxy" type="text" class="text_pole" placeholder="https://api.openai.com/v1" maxlength="100" />
</div>
</div>
<div class="range-block" data-source="openai,claude">
<div class="range-block-title justifyLeft" data-i18n="Proxy Password">
Proxy Password
</div>
<div class="toggle-description justifyLeft">
<span data-i18n="Will be used as a password for the proxy instead of API key.">
Will be used as a password for the proxy instead of API key.<br>
</span>
</div>
<div class="wide100p">
<input id="openai_proxy_password" type="text" class="text_pole" placeholder="" maxlength="200" />
</div>
</div>
<div class="range-block" data-source="openai,claude">
<div class="range-block-title justifyLeft">
<label for="legacy_streaming" class="checkbox_label">
@ -1550,6 +1563,11 @@
<input id="api_key_openai" name="api_key_openai" class="text_pole flex1" maxlength="500" value="" type="text" autocomplete="off">
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_openai"></div>
</div>
<div id="ReverseProxyWarningMessage2" class="reverse_proxy_warning">
<b data-i18n="Use Proxy password field instead. This input will be ignored.">
Use "Proxy password" field instead. This input will be ignored.
</b>
</div>
<div data-for="api_key_openai" class="neutral_warning">
For privacy reasons, your API key will be hidden after you reload the page.
</div>

View File

@ -448,8 +448,8 @@ function RA_autoconnect(PrevApi) {
}
break;
case 'openai':
if ((secret_state[SECRET_KEYS.OPENAI] && oai_settings.chat_completion_source == chat_completion_sources.OPENAI)
|| (secret_state[SECRET_KEYS.CLAUDE] && oai_settings.chat_completion_source == chat_completion_sources.CLAUDE)
if (((secret_state[SECRET_KEYS.OPENAI] || oai_settings.reverse_proxy) && oai_settings.chat_completion_source == chat_completion_sources.OPENAI)
|| ((secret_state[SECRET_KEYS.CLAUDE] || oai_settings.reverse_proxy) && oai_settings.chat_completion_source == chat_completion_sources.CLAUDE)
|| (secret_state[SECRET_KEYS.SCALE] && oai_settings.chat_completion_source == chat_completion_sources.SCALE)
|| (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI)
|| (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER)

View File

@ -142,6 +142,7 @@ const default_settings = {
max_context_unlocked: false,
api_url_scale: '',
show_external_models: false,
proxy_password: '',
};
const oai_settings = {
@ -178,6 +179,7 @@ const oai_settings = {
max_context_unlocked: false,
api_url_scale: '',
show_external_models: false,
proxy_password: '',
};
let openai_setting_names;
@ -767,6 +769,7 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
if (oai_settings.reverse_proxy && [chat_completion_sources.CLAUDE, chat_completion_sources.OPENAI].includes(oai_settings.chat_completion_source)) {
validateReverseProxy();
generate_data['reverse_proxy'] = oai_settings.reverse_proxy;
generate_data['proxy_password'] = oai_settings.proxy_password;
}
if (isClaude) {
@ -1105,6 +1108,7 @@ function loadOpenAISettings(data, settings) {
oai_settings.chat_completion_source = settings.chat_completion_source ?? default_settings.chat_completion_source;
oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale;
oai_settings.show_external_models = settings.show_external_models ?? default_settings.show_external_models;
oai_settings.proxy_password = settings.proxy_password ?? default_settings.proxy_password;
if (settings.nsfw_toggle !== undefined) oai_settings.nsfw_toggle = !!settings.nsfw_toggle;
if (settings.keep_example_dialogue !== undefined) oai_settings.keep_example_dialogue = !!settings.keep_example_dialogue;
@ -1116,6 +1120,7 @@ function loadOpenAISettings(data, settings) {
$('#stream_toggle').prop('checked', oai_settings.stream_openai);
$('#api_url_scale').val(oai_settings.api_url_scale);
$('#openai_proxy_password').val(oai_settings.proxy_password);
$('#model_openai_select').val(oai_settings.openai_model);
$(`#model_openai_select option[value="${oai_settings.openai_model}"`).attr('selected', true);
@ -1169,9 +1174,7 @@ function loadOpenAISettings(data, settings) {
if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy;
$('#openai_reverse_proxy').val(oai_settings.reverse_proxy);
if (oai_settings.reverse_proxy !== '') {
$("#ReverseProxyWarningMessage").css('display', 'block');
}
$(".reverse_proxy_warning").toggle(oai_settings.reverse_proxy !== '');
$('#openai_logit_bias_preset').empty();
for (const preset of Object.keys(oai_settings.bias_presets)) {
@ -1212,6 +1215,7 @@ async function getStatusOpen() {
let data = {
reverse_proxy: oai_settings.reverse_proxy,
proxy_password: oai_settings.proxy_password,
use_openrouter: oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER,
};
@ -1311,6 +1315,7 @@ async function saveOpenAIPreset(name, settings) {
impersonation_prompt: settings.impersonation_prompt,
bias_preset_selected: settings.bias_preset_selected,
reverse_proxy: settings.reverse_proxy,
proxy_password: settings.proxy_password,
legacy_streaming: settings.legacy_streaming,
max_context_unlocked: settings.max_context_unlocked,
nsfw_avoidance_prompt: settings.nsfw_avoidance_prompt,
@ -1650,6 +1655,7 @@ function onSettingsPresetChange() {
stream_openai: ['#stream_toggle', 'stream_openai', true],
api_url_scale: ['#api_url_scale', 'api_url_scale', false],
show_external_models: ['#openai_show_external_models', 'show_external_models', true],
proxy_password: ['#openai_proxy_password', 'proxy_password', false],
};
for (const [key, [selector, setting, isCheckbox]] of Object.entries(settingsToUpdate)) {
@ -1858,9 +1864,7 @@ async function onNewPresetClick() {
function onReverseProxyInput() {
oai_settings.reverse_proxy = $(this).val();
if (oai_settings.reverse_proxy == '') {
$("#ReverseProxyWarningMessage").css('display', 'none');
} else { $("#ReverseProxyWarningMessage").css('display', 'block'); }
$(".reverse_proxy_warning").toggle(oai_settings.reverse_proxy != '');
saveSettingsDebounced();
}
@ -1912,7 +1916,7 @@ async function onConnectButtonClick(e) {
await writeSecret(SECRET_KEYS.CLAUDE, api_key_claude);
}
if (!secret_state[SECRET_KEYS.CLAUDE]) {
if (!secret_state[SECRET_KEYS.CLAUDE] && !oai_settings.reverse_proxy) {
console.log('No secret key saved for Claude');
return;
}
@ -1925,7 +1929,7 @@ async function onConnectButtonClick(e) {
await writeSecret(SECRET_KEYS.OPENAI, api_key_openai);
}
if (!secret_state[SECRET_KEYS.OPENAI]) {
if (!secret_state[SECRET_KEYS.OPENAI] && !oai_settings.reverse_proxy) {
console.log('No secret key saved for OpenAI');
return;
}
@ -2197,6 +2201,11 @@ $(document).ready(function () {
saveSettingsDebounced();
});
$('#openai_proxy_password').on('input', function () {
oai_settings.proxy_password = $(this).val();
saveSettingsDebounced();
});
$("#api_button_openai").on("click", onConnectButtonClick);
$("#openai_reverse_proxy").on("input", onReverseProxyInput);
$("#model_openai_select").on("change", onModelChange);

View File

@ -2855,7 +2855,7 @@ app.post("/getstatus_openai", jsonParser, function (request, response_getstatus_
if (request.body.use_openrouter == false) {
api_url = new URL(request.body.reverse_proxy || api_openai).toString();
api_key_openai = readSecret(SECRET_KEYS.OPENAI);
api_key_openai = request.body.reverse_proxy ? request.body.proxy_password : readSecret(SECRET_KEYS.OPENAI);
headers = {};
} else {
api_url = 'https://openrouter.ai/api/v1';
@ -2864,7 +2864,7 @@ app.post("/getstatus_openai", jsonParser, function (request, response_getstatus_
headers = { 'HTTP-Referer': request.headers.referer };
}
if (!api_key_openai) {
if (!api_key_openai && !request.body.reverse_proxy) {
return response_getstatus_openai.status(401).send({ error: true });
}
@ -2933,44 +2933,6 @@ app.post("/openai_bias", jsonParser, async function (request, response) {
return response.send(result);
});
// TODO: Dead code, consider deleting. Users will get redirected to OpenAI site instead.
// 'Your request to GET /v1/dashboard/billing/usage must be made with a session key (that is, it can only be made from the browser). You made it with the following key type: secret.'
app.post("/openai_usage", jsonParser, async function (request, response) {
if (!request.body) return response.sendStatus(400);
const key = readSecret(SECRET_KEYS.OPENAI);
if (!key) {
console.warn('Get key usage failed: Missing OpenAI API key.');
return response.sendStatus(401);
}
const api_url = new URL(request.body.reverse_proxy || api_openai).toString();
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${key}`,
};
const date = new Date();
date.setDate(1);
const start_date = date.toISOString().slice(0, 10);
date.setMonth(date.getMonth() + 1);
const end_date = date.toISOString().slice(0, 10);
try {
const res = await getAsync(
`${api_url}/dashboard/billing/usage?start_date=${start_date}&end_date=${end_date}`,
{ headers },
);
return response.send(res);
}
catch (error) {
console.log(error);
return response.sendStatus(400);
}
});
app.post("/deletepreset_openai", jsonParser, function (request, response) {
if (!request.body || !request.body.name) {
return response.sendStatus(400);
@ -3099,7 +3061,7 @@ async function sendClaudeRequest(request, response) {
const fetch = require('node-fetch').default;
const api_url = new URL(request.body.reverse_proxy || api_claude).toString();
const api_key_claude = readSecret(SECRET_KEYS.CLAUDE);
const api_key_claude = request.body.reverse_proxy ? request.body.proxy_password : readSecret(SECRET_KEYS.CLAUDE);
if (!api_key_claude) {
return response.status(401).send({ error: true });
@ -3188,7 +3150,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
if (!request.body.use_openrouter) {
api_url = new URL(request.body.reverse_proxy || api_openai).toString();
api_key_openai = readSecret(SECRET_KEYS.OPENAI);
api_key_openai = request.body.reverse_proxy ? request.body.proxy_password : readSecret(SECRET_KEYS.OPENAI);
headers = {};
} else {
api_url = 'https://openrouter.ai/api/v1';
@ -3197,7 +3159,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
headers = { 'HTTP-Referer': request.headers.referer };
}
if (!api_key_openai) {
if (!api_key_openai && !request.body.reverse_proxy) {
return response_generate_openai.status(401).send({ error: true });
}
@ -3454,17 +3416,6 @@ app.post("/tokenize_via_api", jsonParser, async function (request, response) {
// ** REST CLIENT ASYNC WRAPPERS **
function putAsync(url, args) {
return new Promise((resolve, reject) => {
client.put(url, args, (data, response) => {
if (response.statusCode >= 400) {
reject(data);
}
resolve(data);
}).on('error', e => reject(e));
})
}
async function postAsync(url, args) {
const fetch = require('node-fetch').default;
const response = await fetch(url, { method: 'POST', timeout: 0, ...args });