feature/entra id authentication added

This commit is contained in:
2026-01-15 21:32:35 +01:00
parent 5bbec0e240
commit 2f93fb6cb5
13 changed files with 465 additions and 11 deletions

153
script.js
View File

@@ -1,20 +1,141 @@
const loginScreen = document.getElementById("loginScreen");
const welcomeScreen = document.getElementById("welcomeScreen");
const chatScreen = document.getElementById("chatScreen");
const chatMessages = document.getElementById("chatMessages");
const welcomeInput = document.getElementById("welcomeInput");
const chatInput = document.getElementById("chatInput");
const loginBtn = document.getElementById("loginBtn");
const API_URL = "http://localhost:8000/api/chat";
const API_URL = "http://localhost:8000";
let isInChat = false;
// Auth functions
function getToken() {
return localStorage.getItem("devden_token");
}
function setToken(token) {
localStorage.setItem("devden_token", token);
}
function clearToken() {
localStorage.removeItem("devden_token");
}
function showLoginScreen() {
loginScreen.classList.remove("hidden");
welcomeScreen.classList.add("hidden");
chatScreen.classList.add("hidden");
}
function showWelcomeScreen() {
loginScreen.classList.add("hidden");
welcomeScreen.classList.remove("hidden");
chatScreen.classList.add("hidden");
welcomeInput.focus();
}
function switchToChat() {
loginScreen.classList.add("hidden");
welcomeScreen.classList.add("hidden");
chatScreen.classList.remove("hidden");
chatInput.focus();
isInChat = true;
}
async function checkAuth() {
const token = getToken();
if (!token) {
showLoginScreen();
return;
}
try {
const response = await fetch(`${API_URL}/api/auth/me`, {
headers: { Authorization: `Bearer ${token}` },
});
if (response.ok) {
showWelcomeScreen();
} else {
clearToken();
showLoginScreen();
}
} catch (error) {
console.error("Auth check failed:", error);
showLoginScreen();
}
}
async function handleLogin() {
loginBtn.disabled = true;
loginBtn.textContent = "Redirecting...";
try {
// Check if auth is configured
const statusResponse = await fetch(`${API_URL}/api/auth/status`);
const statusData = await statusResponse.json();
if (!statusData.configured) {
alert(
"Authentication not configured. Please set ENTRA_TENANT_ID, ENTRA_CLIENT_ID, and ENTRA_CLIENT_SECRET in your .env file.",
);
loginBtn.disabled = false;
loginBtn.textContent = "Sign in with Microsoft";
return;
}
// Get auth URL and redirect
const response = await fetch(`${API_URL}/api/auth/login`);
const data = await response.json();
if (data.auth_url) {
window.location.href = data.auth_url;
} else {
throw new Error("No auth URL returned");
}
} catch (error) {
console.error("Login failed:", error);
alert("Login failed: " + error.message);
loginBtn.disabled = false;
loginBtn.textContent = "Sign in with Microsoft";
}
}
async function handleCallback() {
const params = new URLSearchParams(window.location.search);
const code = params.get("code");
if (!code) return false;
try {
const response = await fetch(`${API_URL}/api/auth/callback`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || "Callback failed");
}
const data = await response.json();
setToken(data.token);
// Clean up URL
window.history.replaceState({}, "", "/");
return true;
} catch (error) {
console.error("Callback failed:", error);
alert("Authentication failed: " + error.message);
return false;
}
}
// Chat functions
function addMessage(text, type = "user") {
const msg = document.createElement("div");
msg.className = `message ${type}`;
@@ -69,10 +190,12 @@ async function sendMessage(text) {
showTyping();
try {
const response = await fetch(`${API_URL}/stream`, {
const token = getToken();
const response = await fetch(`${API_URL}/api/chat/stream`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
message: text,
@@ -80,6 +203,13 @@ async function sendMessage(text) {
}),
});
if (response.status === 401) {
hideTyping();
clearToken();
showLoginScreen();
return;
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
@@ -136,7 +266,9 @@ async function sendMessage(text) {
}
}
// Welcome screen input handler
// Event listeners
loginBtn.addEventListener("click", handleLogin);
welcomeInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
@@ -147,10 +279,23 @@ welcomeInput.addEventListener("keydown", (e) => {
}
});
// Chat input handler
chatInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
sendMessage(chatInput.value);
}
});
// Initialize
async function init() {
// Check for OAuth callback first
const callbackSuccess = await handleCallback();
if (callbackSuccess) {
showWelcomeScreen();
} else {
await checkAuth();
}
}
init();