Lashtw's picture
Upload 9 files
90f7646 verified
raw
history blame
4.42 kB
import { auth, db } from "./firebase.js";
import {
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
signOut
} from "https://www.gstatic.com/firebasejs/10.7.1/firebase-auth.js";
import {
doc,
getDoc,
setDoc,
updateDoc,
collection,
getDocs,
deleteDoc,
serverTimestamp,
query
} from "https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js";
const INSTRUCTORS_COLLECTION = "instructors";
const SUPER_ADMIN_EMAIL = "t92206@gmail.com";
/**
* Sign in with Email/Password
*/
export async function loginWithEmail(email, password) {
try {
const result = await signInWithEmailAndPassword(auth, email, password);
return result.user;
} catch (error) {
console.error("Login Error:", error);
throw error;
}
}
/**
* Register with Email/Password
* (Used for new instructors to create their auth account matching their whitelisted email)
*/
export async function registerWithEmail(email, password) {
try {
const result = await createUserWithEmailAndPassword(auth, email, password);
return result.user;
} catch (error) {
console.error("Register Error:", error);
throw error;
}
}
/**
* Sign out
*/
export async function signOutUser() {
try {
await signOut(auth);
} catch (error) {
console.error("Sign Out Error:", error);
throw error;
}
}
/**
* Check if user is an instructor and get permissions
* Bootstraps the Super Admin if not exists
* @param {object} user - Firebase User object
* @returns {Promise<object|null>} Instructor data or null if not authorized
*/
export async function checkInstructorPermission(user) {
if (!user || !user.email) return null;
const email = user.email;
const instructorRef = doc(db, INSTRUCTORS_COLLECTION, email);
const snap = await getDoc(instructorRef);
// Bootstrap Super Admin
if (email === SUPER_ADMIN_EMAIL) {
const adminData = {
name: user.displayName || "Super Admin",
email: email,
role: 'admin',
permissions: ['create_room', 'add_question', 'manage_instructors'],
lastLogin: serverTimestamp()
};
try {
if (!snap.exists()) {
await setDoc(instructorRef, {
...adminData,
createdAt: serverTimestamp()
});
} else {
// Ensure admin always has full permissions
await updateDoc(instructorRef, {
role: 'admin',
permissions: ['create_room', 'add_question', 'manage_instructors'],
lastLogin: serverTimestamp()
});
}
} catch (e) {
console.warn("Admin bootstrap failed (likely permission issues), but allowing login as admin.", e);
// We continue because we return adminData anyway, effectively granting admin rights in UI.
}
return adminData;
}
if (snap.exists()) {
const data = snap.data();
await updateDoc(instructorRef, { lastLogin: serverTimestamp() });
return data;
}
return null; // Not an instructor
}
/**
* Get all instructors (Admin Only)
*/
export async function getInstructors() {
const q = query(collection(db, INSTRUCTORS_COLLECTION));
const snapshot = await getDocs(q);
return snapshot.docs.map(doc => doc.data());
}
/**
* Add new instructor (Admin Only)
*/
export async function addInstructor(email, name, permissions) {
const instructorRef = doc(db, INSTRUCTORS_COLLECTION, email);
await setDoc(instructorRef, {
email,
name,
role: 'instructor',
permissions,
createdAt: serverTimestamp()
});
}
/**
* Update instructor (Admin Only)
*/
export async function updateInstructor(email, data) {
const instructorRef = doc(db, INSTRUCTORS_COLLECTION, email);
await updateDoc(instructorRef, data);
}
/**
* Remove instructor (Admin Only)
*/
export async function removeInstructor(email) {
if (email === SUPER_ADMIN_EMAIL) throw new Error("Cannot remove Super Admin");
await deleteDoc(doc(db, INSTRUCTORS_COLLECTION, email));
}