mirror of https://github.com/dexidp/dex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.1 KiB
154 lines
5.1 KiB
(function() { |
|
const crossClientInput = document.getElementById("cross_client_input"); |
|
const crossClientList = document.getElementById("cross-client-list"); |
|
const addClientBtn = document.getElementById("add-cross-client"); |
|
const scopesList = document.getElementById("scopes-list"); |
|
const customScopeInput = document.getElementById("custom_scope_input"); |
|
const addCustomScopeBtn = document.getElementById("add-custom-scope"); |
|
|
|
// Default scopes that should be checked by default |
|
const defaultScopes = ["openid", "profile", "email", "offline_access"]; |
|
|
|
// Check default scopes on page load |
|
document.addEventListener("DOMContentLoaded", function() { |
|
const checkboxes = scopesList.querySelectorAll('input[type="checkbox"]'); |
|
checkboxes.forEach(cb => { |
|
if (defaultScopes.includes(cb.value)) { |
|
cb.checked = true; |
|
} |
|
}); |
|
}); |
|
|
|
function addCrossClient(value) { |
|
const trimmed = value.trim(); |
|
if (!trimmed) return; |
|
|
|
const chip = document.createElement("div"); |
|
chip.className = "chip"; |
|
|
|
const text = document.createElement("span"); |
|
text.textContent = trimmed; |
|
|
|
const hidden = document.createElement("input"); |
|
hidden.type = "hidden"; |
|
hidden.name = "cross_client"; |
|
hidden.value = trimmed; |
|
|
|
const remove = document.createElement("button"); |
|
remove.type = "button"; |
|
remove.textContent = "×"; |
|
remove.onclick = () => crossClientList.removeChild(chip); |
|
|
|
chip.append(text, hidden, remove); |
|
crossClientList.appendChild(chip); |
|
} |
|
|
|
function addCustomScope(scope) { |
|
const trimmed = scope.trim(); |
|
if (!trimmed || !scopesList) return; |
|
|
|
// Check if scope already exists |
|
const existingCheckboxes = scopesList.querySelectorAll('input[type="checkbox"]'); |
|
for (const cb of existingCheckboxes) { |
|
if (cb.value === trimmed) { |
|
cb.checked = true; |
|
return; |
|
} |
|
} |
|
|
|
// Add new scope checkbox |
|
const scopeItem = document.createElement("div"); |
|
scopeItem.className = "scope-item"; |
|
|
|
const checkbox = document.createElement("input"); |
|
checkbox.type = "checkbox"; |
|
checkbox.name = "extra_scopes"; |
|
checkbox.value = trimmed; |
|
checkbox.id = "scope_custom_" + trimmed; |
|
checkbox.checked = true; |
|
|
|
const label = document.createElement("label"); |
|
label.htmlFor = checkbox.id; |
|
label.textContent = trimmed; |
|
|
|
scopeItem.append(checkbox, label); |
|
scopesList.appendChild(scopeItem); |
|
} |
|
|
|
addClientBtn?.addEventListener("click", () => { |
|
addCrossClient(crossClientInput.value); |
|
crossClientInput.value = ""; |
|
crossClientInput.focus(); |
|
}); |
|
|
|
crossClientInput?.addEventListener("keydown", (e) => { |
|
if (e.key === "Enter") { |
|
e.preventDefault(); |
|
addCrossClient(crossClientInput.value); |
|
crossClientInput.value = ""; |
|
} |
|
}); |
|
|
|
addCustomScopeBtn?.addEventListener("click", () => { |
|
addCustomScope(customScopeInput.value); |
|
customScopeInput.value = ""; |
|
customScopeInput.focus(); |
|
}); |
|
|
|
customScopeInput?.addEventListener("keydown", (e) => { |
|
if (e.key === "Enter") { |
|
e.preventDefault(); |
|
addCustomScope(customScopeInput.value); |
|
customScopeInput.value = ""; |
|
} |
|
}); |
|
|
|
// Device Grant Login Handler |
|
const deviceGrantBtn = document.getElementById("device-grant-btn"); |
|
deviceGrantBtn?.addEventListener("click", async () => { |
|
deviceGrantBtn.disabled = true; |
|
deviceGrantBtn.textContent = "Loading..."; |
|
|
|
try { |
|
// Collect form data similar to regular login |
|
const form = document.getElementById("login-form"); |
|
const formData = new FormData(form); |
|
|
|
// Get selected scopes |
|
const scopes = formData.getAll("extra_scopes"); |
|
|
|
// Get cross-client values |
|
const crossClients = formData.getAll("cross_client"); |
|
|
|
// Get connector_id if specified |
|
const connectorId = formData.get("connector_id") || ""; |
|
|
|
// Initiate device flow with options |
|
const response = await fetch('/device/login', { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
}, |
|
body: JSON.stringify({ |
|
scopes: scopes, |
|
cross_clients: crossClients, |
|
connector_id: connectorId |
|
}) |
|
}); |
|
|
|
if (response.ok) { |
|
// Redirect to device flow page |
|
window.location.href = '/device'; |
|
} else { |
|
const errorText = await response.text(); |
|
alert('Failed to start device flow: ' + errorText); |
|
} |
|
} catch (error) { |
|
alert('Error starting device flow: ' + error.message); |
|
} finally { |
|
deviceGrantBtn.disabled = false; |
|
deviceGrantBtn.textContent = "Device Code Flow"; |
|
} |
|
}); |
|
})(); |
|
|
|
|