feat: add wizard auth selector
This commit is contained in:
+407
-63
@@ -276,9 +276,44 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||
await loadProtocolCapabilities();
|
||||
|
||||
await loadWizardPanels([1, 2, 3, 4, 5]);
|
||||
await loadWizardAuthResources();
|
||||
bindProtocolCards();
|
||||
bindWizardLiveActions();
|
||||
bindStreamingConfigControls();
|
||||
updateUpstreamAuthUi();
|
||||
|
||||
var quickSecretModal = document.getElementById('quick-secret-modal');
|
||||
var quickSecretClose = document.getElementById('quick-secret-close-btn');
|
||||
var quickSecretCancel = document.getElementById('quick-secret-cancel-btn');
|
||||
var quickSecretSubmit = document.getElementById('quick-secret-submit-btn');
|
||||
if (quickSecretClose) quickSecretClose.addEventListener('click', closeQuickSecretModal);
|
||||
if (quickSecretCancel) quickSecretCancel.addEventListener('click', closeQuickSecretModal);
|
||||
if (quickSecretModal) {
|
||||
quickSecretModal.addEventListener('click', function(event) {
|
||||
if (event.target === quickSecretModal) closeQuickSecretModal();
|
||||
});
|
||||
}
|
||||
if (quickSecretSubmit) {
|
||||
quickSecretSubmit.addEventListener('click', async function() {
|
||||
var button = quickSecretSubmit;
|
||||
var original = button.textContent;
|
||||
button.disabled = true;
|
||||
button.textContent = tKey('wizard.step2.quick_secret_submit');
|
||||
try {
|
||||
await submitQuickSecret();
|
||||
} catch (error) {
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.error(
|
||||
error.message || tKey('wizard.toast.quick_secret_error_title'),
|
||||
tKey('wizard.toast.quick_secret_error_title')
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
button.disabled = false;
|
||||
button.textContent = original;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
if (params.get('mode') === 'edit' && params.get('operationId')) {
|
||||
@@ -338,46 +373,170 @@ function selectGqlType(btn) {
|
||||
if (defaults[type]) editor.value = defaults[type];
|
||||
}
|
||||
|
||||
/* ── Upstream selector (Step 3) ── */
|
||||
/* ── Upstream selector (Step 2) ── */
|
||||
|
||||
var upstreams = [
|
||||
{ id: 'acme-api', name: 'acme-api', url: 'https://api.acme.com', authHeaders: '{\n \"Authorization\": \"Bearer ${secrets.ACME_API_TOKEN}\"\n}' },
|
||||
{ id: 'stripe', name: 'stripe-payments', url: 'https://api.stripe.com', authHeaders: '{\n \"Authorization\": \"Bearer ${secrets.STRIPE_API_KEY}\"\n}' },
|
||||
{ id: 'internal-crm', name: 'internal-crm', url: 'https://crm.internal.acme.io', authHeaders: '{\n}' },
|
||||
{ id: 'sendgrid', name: 'sendgrid-mail', url: 'https://api.sendgrid.com', authHeaders: '{\n \"Authorization\": \"Bearer ${secrets.SENDGRID_API_KEY}\"\n}' },
|
||||
{ id: 'twilio', name: 'twilio-sms', url: 'https://api.twilio.com', authHeaders: '{\n \"Authorization\": \"Bearer ${secrets.TWILIO_API_KEY}\"\n}' },
|
||||
{ id: 'open-meteo', name: 'Open Meteo', url: 'https://api.open-meteo.com', staticHeaders: '{}', authProfileId: null, authProfileName: '', authKind: null },
|
||||
{ id: 'countries-graphql', name: 'Countries GraphQL', url: 'https://countries.trevorblades.com', staticHeaders: '{}', authProfileId: null, authProfileName: '', authKind: null },
|
||||
{ id: 'grpcb', name: 'grpcb.in', url: 'https://grpcb.in:443', staticHeaders: '{}', authProfileId: null, authProfileName: '', authKind: null }
|
||||
];
|
||||
|
||||
var wizardSecrets = [];
|
||||
var wizardAuthProfiles = [];
|
||||
var selectedUpstreamId = null;
|
||||
var dropdownOpen = false;
|
||||
var editingUpstreamId = null;
|
||||
|
||||
function inferUpstreamAuth(headersText) {
|
||||
var parsed = parseStructuredText(headersText || '{}');
|
||||
var keys = parsed && typeof parsed === 'object' ? Object.keys(parsed) : [];
|
||||
if (!keys.length) {
|
||||
function authProfileById(authProfileId) {
|
||||
return wizardAuthProfiles.find(function(item) { return item.id === authProfileId; }) || null;
|
||||
}
|
||||
|
||||
function syncUpstreamAuthMetadata(upstream) {
|
||||
if (!upstream) return upstream;
|
||||
if (!upstream.authProfileId) {
|
||||
upstream.authProfileName = '';
|
||||
upstream.authKind = null;
|
||||
return upstream;
|
||||
}
|
||||
|
||||
var profile = authProfileById(upstream.authProfileId);
|
||||
if (profile) {
|
||||
upstream.authProfileName = profile.name;
|
||||
upstream.authKind = profile.kind;
|
||||
}
|
||||
return upstream;
|
||||
}
|
||||
|
||||
function inferUpstreamAuth(upstream) {
|
||||
syncUpstreamAuthMetadata(upstream);
|
||||
if (!upstream || !upstream.authProfileId || !upstream.authKind) {
|
||||
return { kind: 'none', label: tKey('wizard.step2.auth_none') };
|
||||
}
|
||||
|
||||
var hasAuthorization = keys.some(function(key) {
|
||||
return String(key).toLowerCase() === 'authorization';
|
||||
});
|
||||
|
||||
if (hasAuthorization) {
|
||||
if (upstream.authKind === 'bearer') {
|
||||
return { kind: 'bearer', label: tKey('wizard.step2.auth_bearer') };
|
||||
}
|
||||
|
||||
if (upstream.authKind === 'basic') {
|
||||
return { kind: 'basic', label: tKey('wizard.step2.auth_basic') };
|
||||
}
|
||||
return { kind: 'apikey', label: tKey('wizard.step2.auth_apikey') };
|
||||
}
|
||||
|
||||
function upstreamMeta(upstream) {
|
||||
var auth = inferUpstreamAuth(upstream && upstream.authHeaders);
|
||||
var auth = inferUpstreamAuth(upstream);
|
||||
return {
|
||||
kind: auth.kind,
|
||||
label: auth.label,
|
||||
};
|
||||
}
|
||||
|
||||
async function loadWizardAuthResources() {
|
||||
if (!wizardWorkspaceId || !window.CrankApi) {
|
||||
wizardSecrets = [];
|
||||
wizardAuthProfiles = [];
|
||||
renderAuthProfileOptions();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var results = await Promise.all([
|
||||
window.CrankApi.listSecrets(wizardWorkspaceId),
|
||||
window.CrankApi.listAuthProfiles(wizardWorkspaceId),
|
||||
]);
|
||||
wizardSecrets = (results[0] && results[0].items) || [];
|
||||
wizardAuthProfiles = (results[1] && results[1].items) || [];
|
||||
} catch (_error) {
|
||||
wizardSecrets = [];
|
||||
wizardAuthProfiles = [];
|
||||
}
|
||||
|
||||
upstreams.forEach(syncUpstreamAuthMetadata);
|
||||
renderAuthProfileOptions();
|
||||
}
|
||||
|
||||
function renderAuthProfileOptions() {
|
||||
var profileSelect = document.getElementById('new-upstream-auth-profile');
|
||||
var secretSelect = document.getElementById('new-auth-profile-secret-id');
|
||||
var usernameSelect = document.getElementById('new-auth-profile-username-secret');
|
||||
var passwordSelect = document.getElementById('new-auth-profile-password-secret');
|
||||
var profileHint = document.getElementById('new-upstream-auth-profile-hint');
|
||||
|
||||
if (profileSelect) {
|
||||
var previousProfile = profileSelect.value;
|
||||
profileSelect.innerHTML = '';
|
||||
if (!wizardAuthProfiles.length) {
|
||||
var emptyProfile = document.createElement('option');
|
||||
emptyProfile.value = '';
|
||||
emptyProfile.textContent = tKey('wizard.step2.auth_profile_empty');
|
||||
profileSelect.appendChild(emptyProfile);
|
||||
if (profileHint) profileHint.textContent = tKey('wizard.step2.auth_profile_empty');
|
||||
} else {
|
||||
var placeholder = document.createElement('option');
|
||||
placeholder.value = '';
|
||||
placeholder.textContent = tKey('wizard.step2.auth_profile');
|
||||
profileSelect.appendChild(placeholder);
|
||||
wizardAuthProfiles.forEach(function(profile) {
|
||||
var option = document.createElement('option');
|
||||
option.value = profile.id;
|
||||
option.textContent = profile.name + ' · ' + profile.kind;
|
||||
profileSelect.appendChild(option);
|
||||
});
|
||||
if (previousProfile) {
|
||||
profileSelect.value = previousProfile;
|
||||
}
|
||||
if (profileHint) profileHint.textContent = tKey('wizard.step2.auth_profile_hint');
|
||||
}
|
||||
}
|
||||
|
||||
[secretSelect, usernameSelect, passwordSelect].forEach(function(select) {
|
||||
if (!select) return;
|
||||
var previous = select.value;
|
||||
select.innerHTML = '';
|
||||
var placeholder = document.createElement('option');
|
||||
placeholder.value = '';
|
||||
placeholder.textContent = tKey('wizard.step2.secret_value');
|
||||
select.appendChild(placeholder);
|
||||
wizardSecrets.forEach(function(secret) {
|
||||
var option = document.createElement('option');
|
||||
option.value = secret.id;
|
||||
option.textContent = secret.name + ' · ' + secret.kind;
|
||||
select.appendChild(option);
|
||||
});
|
||||
if (previous) {
|
||||
select.value = previous;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateAuthProfileCreateUi() {
|
||||
var kind = textValue('new-auth-profile-kind') || 'bearer';
|
||||
var headerGroup = document.getElementById('auth-profile-header-name-group');
|
||||
var queryGroup = document.getElementById('auth-profile-query-param-group');
|
||||
var basicRow = document.getElementById('auth-profile-basic-secret-row');
|
||||
var singleSecretGroup = document.getElementById('auth-profile-single-secret-group');
|
||||
|
||||
if (headerGroup) {
|
||||
headerGroup.style.display = (kind === 'bearer' || kind === 'api_key_header') ? '' : 'none';
|
||||
}
|
||||
if (queryGroup) {
|
||||
queryGroup.style.display = kind === 'api_key_query' ? '' : 'none';
|
||||
}
|
||||
if (basicRow) {
|
||||
basicRow.style.display = kind === 'basic' ? '' : 'none';
|
||||
}
|
||||
if (singleSecretGroup) {
|
||||
singleSecretGroup.style.display = kind === 'basic' ? 'none' : '';
|
||||
}
|
||||
}
|
||||
|
||||
function updateUpstreamAuthUi() {
|
||||
var mode = textValue('new-upstream-auth-mode') || 'none';
|
||||
var existingGroup = document.getElementById('upstream-auth-existing-group');
|
||||
var createGroup = document.getElementById('upstream-auth-create-group');
|
||||
if (existingGroup) existingGroup.style.display = mode === 'existing' ? '' : 'none';
|
||||
if (createGroup) createGroup.style.display = mode === 'create' ? '' : 'none';
|
||||
updateAuthProfileCreateUi();
|
||||
}
|
||||
|
||||
function renderDropdownList(filter) {
|
||||
var list = document.getElementById('upstream-dropdown-list');
|
||||
if (!list) return;
|
||||
@@ -522,7 +681,17 @@ function startNewUpstream() {
|
||||
form.style.display = '';
|
||||
setValue('new-upstream-name', '');
|
||||
setValue('new-upstream-url', '');
|
||||
setValue('new-upstream-auth-headers', '{\n}');
|
||||
setValue('new-upstream-static-headers', '{\n}');
|
||||
setValue('new-upstream-auth-mode', 'none');
|
||||
setValue('new-upstream-auth-profile', '');
|
||||
setValue('new-auth-profile-name', '');
|
||||
setValue('new-auth-profile-kind', 'bearer');
|
||||
setValue('new-auth-profile-header-name', 'Authorization');
|
||||
setValue('new-auth-profile-query-param', 'api_key');
|
||||
setValue('new-auth-profile-secret-id', '');
|
||||
setValue('new-auth-profile-username-secret', '');
|
||||
setValue('new-auth-profile-password-secret', '');
|
||||
updateUpstreamAuthUi();
|
||||
var first = form.querySelector('input');
|
||||
if (first) setTimeout(function() { first.focus(); }, 50);
|
||||
}
|
||||
@@ -545,46 +714,151 @@ function beginEditSelectedUpstream(e) {
|
||||
form.style.display = '';
|
||||
setValue('new-upstream-name', upstream.name);
|
||||
setValue('new-upstream-url', upstream.url);
|
||||
setValue('new-upstream-auth-headers', upstream.authHeaders || '{\n}');
|
||||
setValue('new-upstream-static-headers', upstream.staticHeaders || '{\n}');
|
||||
setValue('new-upstream-auth-profile', upstream.authProfileId || '');
|
||||
setValue('new-upstream-auth-mode', upstream.authProfileId ? 'existing' : 'none');
|
||||
updateUpstreamAuthUi();
|
||||
}
|
||||
}
|
||||
|
||||
function saveNewUpstream(e) {
|
||||
e.stopPropagation();
|
||||
var nameEl = document.getElementById('new-upstream-name');
|
||||
var urlEl = document.getElementById('new-upstream-url');
|
||||
var name = nameEl ? nameEl.value.trim() : '';
|
||||
var url = urlEl ? urlEl.value.trim() : '';
|
||||
if (!name) { if (nameEl) nameEl.focus(); return; }
|
||||
if (!url) { if (urlEl) urlEl.focus(); return; }
|
||||
|
||||
var authHeadersEl = document.getElementById('new-upstream-auth-headers');
|
||||
var authHeaders = authHeadersEl ? authHeadersEl.value : '{\n}';
|
||||
var nextRecord = {
|
||||
id: editingUpstreamId || ('custom-' + Date.now()),
|
||||
name: name,
|
||||
url: url,
|
||||
authHeaders: authHeaders
|
||||
};
|
||||
|
||||
if (editingUpstreamId) {
|
||||
upstreams = upstreams.map(function(item) {
|
||||
return item.id === editingUpstreamId ? nextRecord : item;
|
||||
});
|
||||
} else {
|
||||
upstreams.push(nextRecord);
|
||||
function buildAuthProfileConfig(kind) {
|
||||
if (kind === 'bearer') {
|
||||
var bearerHeader = textValue('new-auth-profile-header-name') || 'Authorization';
|
||||
var bearerSecretId = textValue('new-auth-profile-secret-id');
|
||||
if (!bearerHeader) throw new Error(tKey('wizard.error.header_name_required'));
|
||||
if (!bearerSecretId) throw new Error(tKey('wizard.error.secret_required'));
|
||||
return {
|
||||
bearer: {
|
||||
header_name: bearerHeader,
|
||||
secret_id: bearerSecretId,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Reset form
|
||||
if (nameEl) nameEl.value = '';
|
||||
if (urlEl) urlEl.value = '';
|
||||
if (authHeadersEl) authHeadersEl.value = '{\n}';
|
||||
var form = document.getElementById('upstream-new-form');
|
||||
if (form) form.style.display = 'none';
|
||||
editingUpstreamId = null;
|
||||
if (kind === 'basic') {
|
||||
var usernameSecretId = textValue('new-auth-profile-username-secret');
|
||||
var passwordSecretId = textValue('new-auth-profile-password-secret');
|
||||
if (!usernameSecretId || !passwordSecretId) throw new Error(tKey('wizard.error.basic_secrets_required'));
|
||||
return {
|
||||
basic: {
|
||||
username_secret_id: usernameSecretId,
|
||||
password_secret_id: passwordSecretId,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Select the new upstream
|
||||
pickUpstream(nextRecord.id);
|
||||
if (kind === 'api_key_header') {
|
||||
var headerName = textValue('new-auth-profile-header-name');
|
||||
var headerSecretId = textValue('new-auth-profile-secret-id');
|
||||
if (!headerName) throw new Error(tKey('wizard.error.header_name_required'));
|
||||
if (!headerSecretId) throw new Error(tKey('wizard.error.secret_required'));
|
||||
return {
|
||||
api_key_header: {
|
||||
header_name: headerName,
|
||||
secret_id: headerSecretId,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var queryParam = textValue('new-auth-profile-query-param');
|
||||
var querySecretId = textValue('new-auth-profile-secret-id');
|
||||
if (!queryParam) throw new Error(tKey('wizard.error.query_param_required'));
|
||||
if (!querySecretId) throw new Error(tKey('wizard.error.secret_required'));
|
||||
return {
|
||||
api_key_query: {
|
||||
param_name: queryParam,
|
||||
secret_id: querySecretId,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function createAuthProfileFromForm() {
|
||||
var name = textValue('new-auth-profile-name');
|
||||
var kind = textValue('new-auth-profile-kind') || 'bearer';
|
||||
if (!name) throw new Error(tKey('wizard.error.auth_profile_name'));
|
||||
|
||||
var profile = await window.CrankApi.createAuthProfile(wizardWorkspaceId, {
|
||||
name: name,
|
||||
kind: kind,
|
||||
config: buildAuthProfileConfig(kind),
|
||||
});
|
||||
wizardAuthProfiles.push(profile);
|
||||
renderAuthProfileOptions();
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.success(
|
||||
tKey('wizard.toast.auth_profile_created_body'),
|
||||
tKey('wizard.toast.auth_profile_created_title')
|
||||
);
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
async function saveNewUpstream(e) {
|
||||
e.stopPropagation();
|
||||
try {
|
||||
var nameEl = document.getElementById('new-upstream-name');
|
||||
var urlEl = document.getElementById('new-upstream-url');
|
||||
var name = nameEl ? nameEl.value.trim() : '';
|
||||
var url = urlEl ? urlEl.value.trim() : '';
|
||||
if (!name) { if (nameEl) nameEl.focus(); return; }
|
||||
if (!url) { if (urlEl) urlEl.focus(); return; }
|
||||
|
||||
var staticHeadersEl = document.getElementById('new-upstream-static-headers');
|
||||
var staticHeaders = staticHeadersEl ? staticHeadersEl.value : '{\n}';
|
||||
parseHeaderMap(staticHeaders);
|
||||
|
||||
var authMode = textValue('new-upstream-auth-mode') || 'none';
|
||||
var authProfileId = null;
|
||||
var authProfileName = '';
|
||||
var authKind = null;
|
||||
|
||||
if (authMode === 'existing') {
|
||||
authProfileId = textValue('new-upstream-auth-profile');
|
||||
if (!authProfileId) throw new Error(tKey('wizard.error.auth_profile_required'));
|
||||
var existingProfile = authProfileById(authProfileId);
|
||||
authProfileName = existingProfile ? existingProfile.name : '';
|
||||
authKind = existingProfile ? existingProfile.kind : null;
|
||||
} else if (authMode === 'create') {
|
||||
var createdProfile = await createAuthProfileFromForm();
|
||||
authProfileId = createdProfile.id;
|
||||
authProfileName = createdProfile.name;
|
||||
authKind = createdProfile.kind;
|
||||
setValue('new-upstream-auth-profile', createdProfile.id);
|
||||
setValue('new-upstream-auth-mode', 'existing');
|
||||
}
|
||||
var nextRecord = {
|
||||
id: editingUpstreamId || ('custom-' + Date.now()),
|
||||
name: name,
|
||||
url: url,
|
||||
staticHeaders: staticHeaders,
|
||||
authProfileId: authProfileId,
|
||||
authProfileName: authProfileName,
|
||||
authKind: authKind,
|
||||
};
|
||||
|
||||
if (editingUpstreamId) {
|
||||
upstreams = upstreams.map(function(item) {
|
||||
return item.id === editingUpstreamId ? nextRecord : item;
|
||||
});
|
||||
} else {
|
||||
upstreams.push(nextRecord);
|
||||
}
|
||||
|
||||
if (nameEl) nameEl.value = '';
|
||||
if (urlEl) urlEl.value = '';
|
||||
if (staticHeadersEl) staticHeadersEl.value = '{\n}';
|
||||
var form = document.getElementById('upstream-new-form');
|
||||
if (form) form.style.display = 'none';
|
||||
editingUpstreamId = null;
|
||||
pickUpstream(nextRecord.id);
|
||||
} catch (error) {
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.error(
|
||||
error.message || tKey('wizard.toast.auth_profile_error_title'),
|
||||
tKey('wizard.toast.auth_profile_error_title')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cancelNewUpstream(e) {
|
||||
@@ -596,6 +870,58 @@ function cancelNewUpstream(e) {
|
||||
editingUpstreamId = null;
|
||||
}
|
||||
|
||||
function openQuickSecretModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
var modal = document.getElementById('quick-secret-modal');
|
||||
if (!modal) return;
|
||||
setValue('quick-secret-name', '');
|
||||
setValue('quick-secret-value', '');
|
||||
setValue('quick-secret-kind', 'token');
|
||||
modal.classList.add('open');
|
||||
setTimeout(function() {
|
||||
var input = document.getElementById('quick-secret-name');
|
||||
if (input) input.focus();
|
||||
}, 30);
|
||||
}
|
||||
|
||||
function closeQuickSecretModal() {
|
||||
var modal = document.getElementById('quick-secret-modal');
|
||||
if (modal) modal.classList.remove('open');
|
||||
}
|
||||
|
||||
async function submitQuickSecret() {
|
||||
var name = textValue('quick-secret-name');
|
||||
var value = textValue('quick-secret-value');
|
||||
var kind = textValue('quick-secret-kind') || 'token';
|
||||
if (!name) throw new Error(tKey('wizard.error.secret_name_required'));
|
||||
if (!value) throw new Error(tKey('wizard.error.secret_value_required'));
|
||||
|
||||
var secret = await window.CrankApi.createSecret(wizardWorkspaceId, {
|
||||
name: name,
|
||||
kind: kind,
|
||||
value: value,
|
||||
});
|
||||
wizardSecrets.push(secret);
|
||||
renderAuthProfileOptions();
|
||||
var primarySelect = document.getElementById('new-auth-profile-secret-id');
|
||||
var usernameSelect = document.getElementById('new-auth-profile-username-secret');
|
||||
var passwordSelect = document.getElementById('new-auth-profile-password-secret');
|
||||
if (primarySelect && primarySelect.offsetParent !== null) {
|
||||
primarySelect.value = secret.id;
|
||||
} else if (usernameSelect && !usernameSelect.value) {
|
||||
usernameSelect.value = secret.id;
|
||||
} else if (passwordSelect) {
|
||||
passwordSelect.value = secret.id;
|
||||
}
|
||||
closeQuickSecretModal();
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.success(
|
||||
tKey('wizard.toast.quick_secret_created_body'),
|
||||
tKey('wizard.toast.quick_secret_created_title')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
||||
}
|
||||
@@ -1154,10 +1480,17 @@ function parseExecutionConfig(text) {
|
||||
var value = parseStructuredText(text);
|
||||
var retry = value.retry || value.retry_policy || null;
|
||||
var headers = value.headers && typeof value.headers === 'object' ? value.headers : {};
|
||||
var selectedUpstream = currentUpstream();
|
||||
if (selectedUpstream && selectedUpstream.authMode === 'create') {
|
||||
throw new Error(tKey('wizard.error.save_upstream_first'));
|
||||
}
|
||||
var authProfileRef = selectedUpstream && selectedUpstream.authProfileId
|
||||
? selectedUpstream.authProfileId
|
||||
: (value.auth && value.auth.profile ? value.auth.profile : null);
|
||||
var config = {
|
||||
timeout_ms: Number(value.timeout_ms || 10000),
|
||||
retry_policy: retry && retry.max_attempts ? { max_attempts: Number(retry.max_attempts) } : null,
|
||||
auth_profile_ref: value.auth && value.auth.profile ? value.auth.profile : null,
|
||||
auth_profile_ref: authProfileRef,
|
||||
headers: headers,
|
||||
protocol_options: null,
|
||||
};
|
||||
@@ -1185,12 +1518,18 @@ function currentUpstream() {
|
||||
var customUrl = textValue('new-upstream-url');
|
||||
if (!customUrl) return null;
|
||||
|
||||
var authHeaders = textValue('new-upstream-auth-headers');
|
||||
var authMode = textValue('new-upstream-auth-mode') || 'none';
|
||||
var authProfileId = authMode === 'existing' ? textValue('new-upstream-auth-profile') : null;
|
||||
var authProfile = authProfileById(authProfileId);
|
||||
return {
|
||||
id: 'custom',
|
||||
name: customName || 'custom-upstream',
|
||||
url: customUrl,
|
||||
authHeaders: authHeaders,
|
||||
staticHeaders: textValue('new-upstream-static-headers') || '{\n}',
|
||||
authMode: authMode,
|
||||
authProfileId: authProfileId || null,
|
||||
authProfileName: authProfile ? authProfile.name : '',
|
||||
authKind: authProfile ? authProfile.kind : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1230,7 +1569,7 @@ function buildTarget() {
|
||||
base_url: upstream.url,
|
||||
method: activeMethod ? activeMethod.dataset.method : 'POST',
|
||||
path_template: pathTemplate,
|
||||
static_headers: parseHeaderMap(upstream.authHeaders),
|
||||
static_headers: parseHeaderMap(upstream.staticHeaders),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1634,8 +1973,10 @@ function selectProtocol(protocol) {
|
||||
updateWizardProtocolVisibility();
|
||||
}
|
||||
|
||||
function prefillUpstream(baseUrl, headers) {
|
||||
var known = upstreams.find(function(item) { return item.url === baseUrl; });
|
||||
function prefillUpstream(baseUrl, headers, authProfileRef) {
|
||||
var known = upstreams.find(function(item) {
|
||||
return item.url === baseUrl && (item.authProfileId || null) === (authProfileRef || null);
|
||||
});
|
||||
if (known) {
|
||||
pickUpstream(known.id);
|
||||
return;
|
||||
@@ -1648,7 +1989,10 @@ function prefillUpstream(baseUrl, headers) {
|
||||
if (form) form.style.display = '';
|
||||
setValue('new-upstream-name', 'imported-upstream');
|
||||
setValue('new-upstream-url', baseUrl);
|
||||
setValue('new-upstream-auth-headers', headers && Object.keys(headers).length ? JSON.stringify(headers, null, 2) : '{\n}');
|
||||
setValue('new-upstream-static-headers', headers && Object.keys(headers).length ? JSON.stringify(headers, null, 2) : '{\n}');
|
||||
setValue('new-upstream-auth-mode', authProfileRef ? 'existing' : 'none');
|
||||
setValue('new-upstream-auth-profile', authProfileRef || '');
|
||||
updateUpstreamAuthUi();
|
||||
|
||||
var valueEl = document.getElementById('upstream-combobox-value');
|
||||
if (valueEl) {
|
||||
@@ -1725,7 +2069,7 @@ function prefillWizardFromEdit(detail, versionDocument) {
|
||||
|
||||
var target = versionDocument.target || {};
|
||||
if (target.kind === 'rest') {
|
||||
prefillUpstream(target.base_url, target.static_headers);
|
||||
prefillUpstream(target.base_url, target.static_headers, versionDocument.execution_config ? versionDocument.execution_config.auth_profile_ref : null);
|
||||
setValue('endpoint-path', target.path_template);
|
||||
document.querySelectorAll('.method-card').forEach(function(card) {
|
||||
card.classList.toggle('active', card.dataset.method === target.method);
|
||||
@@ -1733,14 +2077,14 @@ function prefillWizardFromEdit(detail, versionDocument) {
|
||||
} else if (target.kind === 'graphql') {
|
||||
var endpoint = target.endpoint || '';
|
||||
var parsedEndpoint = new URL(endpoint, window.location.origin);
|
||||
prefillUpstream(parsedEndpoint.origin, {});
|
||||
prefillUpstream(parsedEndpoint.origin, {}, versionDocument.execution_config ? versionDocument.execution_config.auth_profile_ref : null);
|
||||
setValue('endpoint-path', parsedEndpoint.pathname + parsedEndpoint.search);
|
||||
setValue('gql-query-editor', target.query_template);
|
||||
document.querySelectorAll('.gql-type-card').forEach(function(card) {
|
||||
card.classList.toggle('active', card.dataset.gqlType === target.operation_type);
|
||||
});
|
||||
} else if (target.kind === 'grpc') {
|
||||
prefillUpstream(target.server_addr, {});
|
||||
prefillUpstream(target.server_addr, {}, versionDocument.execution_config ? versionDocument.execution_config.auth_profile_ref : null);
|
||||
var route = '/' + (target.package ? target.package + '.' : '') + target.service + '/' + target.method;
|
||||
setValue('grpc-manual-route', route);
|
||||
setValue('grpc-manual-req-type', '');
|
||||
|
||||
Reference in New Issue
Block a user