diff --git a/Databases/ecobuddy.sqlite b/Databases/ecobuddy.sqlite index 62cde21..aba5aa9 100644 Binary files a/Databases/ecobuddy.sqlite and b/Databases/ecobuddy.sqlite differ diff --git a/Databases/user_credentials.txt b/Databases/user_credentials.txt deleted file mode 100644 index b28078b..0000000 --- a/Databases/user_credentials.txt +++ /dev/null @@ -1,51 +0,0 @@ -Username,Password -Dylan,MirageAutumnUmbrella7 -Lawrence,MirageVictoryKingdom5 -Bryan,EmeraldOrchardLegend3 -Alan,ThunderOceanDiamond2 -Frank,XylophoneVictoryHarmony3 -Logan,NatureSerenityXylophone5 -Jerry,LighthousePhoenixYellow8 -Harold,IcebergGlacierTiger8 -Keith,YachtJourneyGarden4 -Arthur,VictoryOrchardFlower0 -Louis,FlowerNebulaNature3 -Paul,LegendLegendYacht4 -Aaron,RiverCascadeApple3 -George,MeadowBreezePalace4 -Carl,RadianceMirageQuasar2 -Kenneth,IcebergPlanetHorizon8 -Daniel,BreezeXylophoneGalaxy5 -Ronald,PhoenixThunderZephyr2 -Benjamin,NatureVolcanoNebula8 -Joe,UnicornSapphireHorizon1 -Larry,IslandZebraApple6 -Zachary,SapphireUnicornJasmine0 -Willie,UmbrellaVictoryHorizon8 -Anthony,QueenZebraNebula9 -Michael,TigerMountainNightfall8 -Vincent,InfinityHorizonQuicksilver8 -Roger,WinterXylophonePalace8 -Kyle,IcebergDolphinDragon9 -Henry,HarmonyKnightPalace7 -Eugene,JourneyThunderPalace0 -Billy,ThunderThunderQuicksilver9 -Peter,OrchardJasmineVictory4 -Christopher,QueenThunderAutumn5 -Adam,SummerUnicornThunder7 -Nathan,SerenityOrchardThunder2 -Edward,MeadowGalaxyYellow6 -Eric,DolphinNebulaYacht8 -Brian,CastleFlowerGlacier4 -Alexander,ForestSapphireZebra4 -Andrew,GalaxyLemonApple0 -Brandon,HarmonyTigerHarmony2 -Russell,CherryZebraQuicksilver8 -Jack,OrchardZephyrSapphire8 -Jose,BananaJungleSerenity8 -Jacob,KaleidoscopeEmeraldJasmine5 -Dennis,KnightFlowerRainbow2 -Donald,WhisperQuicksilverCastle1 -William,ApplePalaceSummer6 -Patrick,CastleInfinityPhoenix9 -Timothy,YellowEagleSummer0 diff --git a/Views/index.phtml b/Views/index.phtml index 7200fd3..0e14141 100755 --- a/Views/index.phtml +++ b/Views/index.phtml @@ -83,12 +83,12 @@ require('template/header.phtml') // Validate authentication with server first let isAdmin = false; - if (simpleAuth.isAuthenticated()) { + if (auth.isAuthenticated()) { try { // This will validate the token with the server and handle refresh if needed - const isValid = await simpleAuth.validateOnLoad(); + const isValid = await auth.validateOnLoad(); if (isValid) { - isAdmin = simpleAuth.isAdmin(); + isAdmin = auth.isAdmin(); } } catch (error) { console.error('Error validating authentication:', error); diff --git a/Views/template/createModal.phtml b/Views/template/createModal.phtml index 3deb410..01aab45 100755 --- a/Views/template/createModal.phtml +++ b/Views/template/createModal.phtml @@ -96,12 +96,12 @@ createModal.addEventListener('show.bs.modal', async function(event) { // Validate authentication with server first let isAdmin = false; - if (simpleAuth.isAuthenticated()) { + if (auth.isAuthenticated()) { try { // This will validate the token with the server and handle refresh if needed - const isValid = await simpleAuth.validateOnLoad(); + const isValid = await auth.validateOnLoad(); if (isValid) { - isAdmin = simpleAuth.isAdmin(); + isAdmin = auth.isAdmin(); } } catch (error) { console.error('Error validating authentication:', error); diff --git a/Views/template/footer.phtml b/Views/template/footer.phtml index e9d4b6e..940b0f3 100755 --- a/Views/template/footer.phtml +++ b/Views/template/footer.phtml @@ -15,7 +15,7 @@ - + @@ -55,12 +55,12 @@ // initialise CommentsManager CommentsManager.state.isDomReady = true; - if (window.simpleAuth) { + if (window.auth) { CommentsManager.state.isAuthReady = true; CommentsManager.checkinitialise(); } else { - window.addEventListener('simpleAuthReady', () => { - console.log('SimpleAuth is now ready'); + window.addEventListener('authReady', () => { + console.log('auth is now ready'); CommentsManager.state.isAuthReady = true; CommentsManager.checkinitialise(); }); @@ -73,7 +73,7 @@ if (loginForm) { // Show CAPTCHA if needed - if (simpleAuth.needsCaptcha() && captchaContainer) { + if (auth.needsCaptcha() && captchaContainer) { captchaContainer.style.display = 'flex'; } @@ -106,7 +106,7 @@ try { // Attempt login - const result = await simpleAuth.login({ + const result = await auth.login({ username: username, password: password, captchaInput: captchaInput @@ -147,7 +147,7 @@ } // Show CAPTCHA if needed - if (simpleAuth.needsCaptcha() && captchaContainer) { + if (auth.needsCaptcha() && captchaContainer) { captchaContainer.style.display = 'flex'; // Generate new CAPTCHA if needed if (result.captcha) { @@ -178,13 +178,13 @@ if (logoutButton) { logoutButton.addEventListener('click', async (e) => { e.preventDefault(); - await simpleAuth.logout(); + await auth.logout(); }); } // Validate token if authenticated - if (simpleAuth.isAuthenticated()) { - simpleAuth.validateToken().then(valid => { + if (auth.isAuthenticated()) { + auth.validateToken().then(valid => { if (!valid) { if (!localStorage.getItem('validationAttempted')) { localStorage.setItem('validationAttempted', 'true'); diff --git a/Views/template/header.phtml b/Views/template/header.phtml index 6703db6..10ef47e 100755 --- a/Views/template/header.phtml +++ b/Views/template/header.phtml @@ -25,7 +25,7 @@ Ecobuddy - <?php echo $view->pageTitle; ?> - + @@ -66,11 +66,11 @@ // Add client-side authentication check to update UI document.addEventListener('DOMContentLoaded', function() { // Check if user is authenticated on the client side - if (simpleAuth && simpleAuth.isAuthenticated()) { + if (auth && auth.isAuthenticated()) { console.log('User is authenticated on client side'); // Get user data - const user = simpleAuth.getUser(); + const user = auth.getUser(); if (user) { console.log('User data:', user); @@ -115,7 +115,7 @@ const logoutButton = document.getElementById('logoutButton'); if (logoutButton) { logoutButton.addEventListener('click', async function() { - await simpleAuth.logout(); + await auth.logout(); window.location.reload(); }); } @@ -187,10 +187,10 @@ // Validate token with server first let isAuthenticated = false; - if (simpleAuth.isAuthenticated()) { + if (auth.isAuthenticated()) { try { // This will validate the token with the server and handle refresh if needed - isAuthenticated = await simpleAuth.validateOnLoad(); + isAuthenticated = await auth.validateOnLoad(); } catch (error) { console.error('Error validating authentication:', error); isAuthenticated = false; @@ -207,8 +207,8 @@ if (isAuthenticated) { // User is logged in - show user menu - const user = simpleAuth.getUser(); - const isAdmin = simpleAuth.isAdmin(); + const user = auth.getUser(); + const isAdmin = auth.isAdmin(); authSection.innerHTML = `
@@ -233,7 +233,7 @@ const logoutButton = authSection.querySelector('button[name="logoutButton"]'); if (logoutButton) { logoutButton.addEventListener('click', async () => { - await simpleAuth.logout(); + await auth.logout(); window.location.reload(); }); } @@ -250,7 +250,7 @@ // Update auth UI when the page loads document.addEventListener('DOMContentLoaded', updateAuthUI); - // Also update when simpleAuth state changes + // Also update when auth state changes window.addEventListener('storage', function(e) { if (e.key === 'token' || e.key === 'user') { updateAuthUI(); @@ -341,7 +341,7 @@ // Function to update CAPTCHA display async function updateCaptcha() { try { - const captcha = await simpleAuth.generateCaptcha(); + const captcha = await auth.generateCaptcha(); if (captchaDisplay) { captchaDisplay.textContent = captcha; } @@ -363,7 +363,7 @@ } // Show/hide CAPTCHA based on login attempts - if (simpleAuth.needsCaptcha() && captchaContainer) { + if (auth.needsCaptcha() && captchaContainer) { captchaContainer.style.display = 'block'; updateCaptcha(); } @@ -389,7 +389,7 @@ try { // Attempt login - const result = await simpleAuth.login({ + const result = await auth.login({ username, password, captchaInput @@ -448,7 +448,7 @@ } // Hide modal if user is already authenticated - if (simpleAuth.isAuthenticated() && loginModal) { + if (auth.isAuthenticated() && loginModal) { const modalInstance = bootstrap.Modal.getInstance(loginModal); if (modalInstance) { modalInstance.hide(); diff --git a/Views/template/loginModal.phtml b/Views/template/loginModal.phtml index e33173b..a21900c 100755 --- a/Views/template/loginModal.phtml +++ b/Views/template/loginModal.phtml @@ -79,7 +79,7 @@ // Function to update CAPTCHA display async function updateCaptcha() { try { - const captcha = await simpleAuth.generateCaptcha(); + const captcha = await auth.generateCaptcha(); captchaDisplay.textContent = captcha; document.getElementById('captchaCode').value = captcha; } catch (error) { @@ -93,7 +93,7 @@ } // Show/hide CAPTCHA based on login attempts - if (simpleAuth.needsCaptcha()) { + if (auth.needsCaptcha()) { captchaContainer.style.display = 'block'; updateCaptcha(); } @@ -107,7 +107,7 @@ const password = document.getElementById('password').value; const captchaInput = document.getElementById('captchaInput')?.value; - const result = await simpleAuth.login({ + const result = await auth.login({ username, password, captchaInput diff --git a/public/js/apiClient.js b/public/js/apiClient.js index e13d472..ad59bed 100644 --- a/public/js/apiClient.js +++ b/public/js/apiClient.js @@ -5,7 +5,7 @@ * authentication and common request patterns. * * The client uses JWT tokens for authentication, which are automatically - * included in requests via the fetchAuth function provided by the simpleAuth service. + * included in requests via the fetchAuth function provided by the auth service. * * Similar to AuthService.php, great pain and countless tears. And learning woooo!!!!!!!! */ @@ -14,25 +14,25 @@ class ApiClient { * Constructor * * Initialises the API client and sets up the authenticated fetch function. - * Relies on the simpleAuth service being available in the global scope. + * Relies on the auth service being available in the global scope. */ constructor() { // Ensure auth service is available - if (!simpleAuth) { + if (!auth) { console.error('Auth service not available'); } - // Use the fetchAuth method from simpleAuth + // Use the fetchAuth method from auth this.authFetch = async (url, options = {}) => { try { // For unauthenticated requests or when authentication is not required - if (!options.requireAuth || !simpleAuth.isAuthenticated()) { + if (!options.requireAuth || !auth.isAuthenticated()) { return fetch(url, options); } // For authenticated requests delete options.requireAuth; // Remove the custom property - return simpleAuth.fetchAuth(url, options); + return auth.fetchAuth(url, options); } catch (error) { console.error('Error in authFetch:', error); throw error; diff --git a/public/js/simpleAuth.js b/public/js/auth.js similarity index 97% rename from public/js/simpleAuth.js rename to public/js/auth.js index f1b7d0f..77125f7 100644 --- a/public/js/simpleAuth.js +++ b/public/js/auth.js @@ -4,7 +4,7 @@ * I admit JWT is unnecessary, but I did it anyway because it was interesting * and I wanted to try it out. */ -class SimpleAuth { +class Auth { /** * initialise the authentication helper */ @@ -360,13 +360,10 @@ class SimpleAuth { } // Create a global instance and expose it -window.simpleAuth = new SimpleAuth(); +window.auth = new Auth(); -// Also create an alias for backward compatibility -window.auth = window.simpleAuth; - -// Log that simpleAuth is ready -console.log('SimpleAuth is ready and exposed to window'); +// Log that auth is ready +console.log('auth is ready and exposed to window'); // Dispatch a custom event to notify other scripts -window.dispatchEvent(new Event('simpleAuthReady')); \ No newline at end of file +window.dispatchEvent(new Event('authReady')); \ No newline at end of file diff --git a/public/js/comments.js b/public/js/comments.js index 34ddc35..8fcd051 100644 --- a/public/js/comments.js +++ b/public/js/comments.js @@ -7,7 +7,7 @@ const CommentsManager = { // Initialization states state: { isInitializing: false, - isinitialised: false, + isInitialised: false, isDomReady: false, isAuthReady: false }, @@ -16,7 +16,7 @@ const CommentsManager = { * initialise status functionality */ initialise() { - if (this.state.isinitialised) return; + if (this.state.isInitialised) return; console.log('Initializing comments...'); @@ -28,10 +28,10 @@ const CommentsManager = { console.log('Comments initialised with auth state:', { isAuthenticated: this.isAuthenticated(), - user: window.simpleAuth.getUser() + user: window.auth.getUser() }); - this.state.isinitialised = true; + this.state.isInitialised = true; }, /** @@ -49,7 +49,7 @@ const CommentsManager = { * Check if user is authenticated */ isAuthenticated() { - return window.simpleAuth && window.simpleAuth.isAuthenticated(); + return window.auth && window.auth.isAuthenticated(); }, /** @@ -253,8 +253,8 @@ const CommentsManager = { * Creates a comment form dynamically for authenticated users */ createCommentFormForAuthenticatedUser(facilityId) { - // First check if simpleAuth is available - if (!window.simpleAuth) { + // First check if auth is available + if (!window.auth) { return `
@@ -265,9 +265,9 @@ const CommentsManager = { // Validate authentication state try { - const token = window.simpleAuth.getToken(); - const user = window.simpleAuth.getUser(); - const isAuthenticated = window.simpleAuth.isAuthenticated(); + const token = window.auth.getToken(); + const user = window.auth.getUser(); + const isAuthenticated = window.auth.isAuthenticated(); if (!isAuthenticated || !token || !user) { return ` @@ -483,14 +483,14 @@ const CommentsManager = { * Checks if the current user is an admin */ isAdmin() { - return window.simpleAuth && window.simpleAuth.isAdmin(); + return window.auth && window.auth.isAdmin(); }, /** * Checks if the given username matches the current user */ isCurrentUser(username) { - const user = window.simpleAuth && window.simpleAuth.getUser(); + const user = window.auth && window.auth.getUser(); return user && user.username === username; }, @@ -522,21 +522,21 @@ if (document.readyState === 'loading') { CommentsManager.checkinitialise(); } -// Listen for simpleAuth ready -if (window.simpleAuth) { +// Listen for auth ready +if (window.auth) { CommentsManager.state.isAuthReady = true; CommentsManager.checkinitialise(); } else { - window.addEventListener('simpleAuthReady', () => { - console.log('SimpleAuth is now ready'); + window.addEventListener('authReady', () => { + console.log('auth is now ready'); CommentsManager.state.isAuthReady = true; CommentsManager.checkinitialise(); }); // Fallback timeout in case the event doesn't fire setTimeout(() => { - if (!CommentsManager.state.isAuthReady && window.simpleAuth) { - console.log('SimpleAuth found via timeout check'); + if (!CommentsManager.state.isAuthReady && window.auth) { + console.log('auth found via timeout check'); CommentsManager.state.isAuthReady = true; CommentsManager.checkinitialise(); } diff --git a/public/js/facilityData.js b/public/js/facilityData.js index f709b3c..88a7330 100644 --- a/public/js/facilityData.js +++ b/public/js/facilityData.js @@ -272,8 +272,8 @@ function isAdmin() { console.log('Checking admin status...'); // Check if auth service is available and has user data - if (simpleAuth && simpleAuth.getUser()) { - const authUser = simpleAuth.getUser(); + if (auth && auth.getUser()) { + const authUser = auth.getUser(); console.log('Auth service user data:', authUser); console.log('Auth service accessLevel:', authUser.accessLevel); console.log('Auth service isAdmin check:', authUser.accessLevel === 1 || authUser.accessLevel === 0); @@ -302,8 +302,8 @@ function isAdmin() { */ function isAuthenticated() { // Check if auth service is available - if (simpleAuth) { - return simpleAuth.isAuthenticated(); + if (auth) { + return auth.isAuthenticated(); } // Fallback to localStorage @@ -497,8 +497,8 @@ function setupFormHandlers() { // Set the action to 'create' formData.set('action', 'create'); try { - // Use simpleAuth.fetchAuth for authenticated requests - const response = await simpleAuth.fetchAuth('/facilitycontroller.php', { + // Use auth.fetchAuth for authenticated requests + const response = await auth.fetchAuth('/facilitycontroller.php', { method: 'POST', body: formData }); @@ -605,8 +605,8 @@ function setupFormHandlers() { } try { - // Use simpleAuth.fetchAuth for authenticated requests - const response = await simpleAuth.fetchAuth('/facilitycontroller.php', { + // Use auth.fetchAuth for authenticated requests + const response = await auth.fetchAuth('/facilitycontroller.php', { method: 'POST', body: serverFormData }); @@ -694,19 +694,19 @@ function setupFormHandlers() { try { // Check if token is valid - if (!simpleAuth) { + if (!auth) { throw new Error('Auth service not available'); } // Validate token with server before proceeding console.log('Validating token with server...'); - const isValid = await simpleAuth.validateToken(); + const isValid = await auth.validateToken(); if (!isValid) { throw new Error('Authentication token is invalid or expired'); } // Get token after validation to ensure it's fresh - const token = simpleAuth.getToken(); + const token = auth.getToken(); console.log('Using token for delete request:', token); if (!token) { @@ -714,16 +714,16 @@ function setupFormHandlers() { } // Decode token to check payload - if (simpleAuth.parseJwt) { - const payload = simpleAuth.parseJwt(token); + if (auth.parseJwt) { + const payload = auth.parseJwt(token); console.log('Token payload:', payload); console.log('Access level:', payload.accessLevel); console.log('Is admin check:', payload.accessLevel === 0 || payload.accessLevel === 1); } - // Use simpleAuth.fetchAuth for authenticated requests + // Use auth.fetchAuth for authenticated requests console.log('Sending delete request to server...'); - const response = await simpleAuth.fetchAuth('/facilitycontroller.php', { + const response = await auth.fetchAuth('/facilitycontroller.php', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, diff --git a/public/js/mapHandler.js b/public/js/mapHandler.js index 4804bd9..9d6814c 100644 --- a/public/js/mapHandler.js +++ b/public/js/mapHandler.js @@ -92,84 +92,6 @@ document.addEventListener('DOMContentLoaded', function() { setupHeaderSearchHandler(); }); -/** - * Get postcode from coordinates using postcodes.io API - * @param {number} lat - Latitude - * @param {number} lng - Longitude - * @returns {Promise} The postcode - */ -async function getPostcodeFromCoordinates(lat, lng) { - try { - const response = await fetch(`https://api.postcodes.io/postcodes?lon=${lng}&lat=${lat}`); - if (!response.ok) { - throw new Error('Could not find postcode for coordinates'); - } - - const data = await response.json(); - if (data.status === 200 && data.result && data.result.length > 0) { - return data.result[0].postcode; - } - - throw new Error('No postcode found for coordinates'); - } catch (error) { - console.error('Error getting postcode from coordinates:', error); - throw error; - } -} - -/** - * Handle geolocation success - * @param {GeolocationPosition} position - The position object - */ -async function handleGeolocationSuccess(position) { - try { - const { latitude, longitude } = position.coords; - - // Get postcode from coordinates - const postcode = await getPostcodeFromCoordinates(latitude, longitude); - - // Update the postcode input - const postcodeInput = document.getElementById('postcode'); - if (postcodeInput) { - postcodeInput.value = postcode; - - // Submit the form to update the map - const postcodeForm = document.getElementById('postcodeForm'); - if (postcodeForm) { - postcodeForm.dispatchEvent(new Event('submit')); - } - } - } catch (error) { - console.error('Error processing geolocation:', error); - alert('Error getting your location: ' + error.message); - } -} - -/** - * Handle geolocation error - * @param {GeolocationPositionError} error - The error object - */ -function handleGeolocationError(error) { - console.error('Geolocation error:', error); - let message = 'Error getting your location: '; - - switch(error.code) { - case error.PERMISSION_DENIED: - message += 'Please enable location access in your browser settings.'; - break; - case error.POSITION_UNAVAILABLE: - message += 'Location information is unavailable.'; - break; - case error.TIMEOUT: - message += 'Location request timed out.'; - break; - default: - message += 'An unknown error occurred.'; - } - - alert(message); -} - /** * Set up form handlers for postcode and radius inputs */ @@ -245,11 +167,13 @@ function setupFormHandlers() { } if (radiusSelect) { - radiusSelect.addEventListener('change', function() { + radiusSelect.addEventListener('change', async function(e) { + e.preventDefault(); + + const postcode = document.getElementById('postcode').value; + const coords = await getPostcodeCoordinates(postcode); const radius = parseFloat(this.value); - if (currentPostcode) { - updateMapLocation(null, radius); // null coords means use existing center - } + updateMapLocation(coords, radius); }); } } @@ -402,7 +326,7 @@ function toRad(degrees) { * @returns {string} HTML content for popup */ function createPopupContent(facility) { - const isAuthenticated = window.simpleAuth && window.simpleAuth.isAuthenticated(); + const isAuthenticated = window.auth && window.auth.isAuthenticated(); return `
@@ -498,7 +422,7 @@ async function handleCommentSubmit(event, facilityId) { event.preventDefault(); // Check authentication - if (!window.simpleAuth || !window.simpleAuth.isAuthenticated()) { + if (!window.auth || !window.auth.isAuthenticated()) { alert('You must be logged in to add comments'); return false; }