1import { afterLoginUrl } from 'internal/intent'; 2import { oauthConfig } from 'constants/oauth'; 3import { apiLogInOauth, apiSetOauthUsername } from 'internal/endpoints'; 4import { contentLoadingGeneric } from 'internal/loading'; 5import { closeModal1, showMiniModal, showModal1 } from 'internal/modals'; 6import { dataApiPostOrPut } from 'internal/requestHandling'; 7 8// Initialize OAuth providers 9export function initializeOAuth() { 10 // Wait for Google Identity Services to load 11 if (typeof google === 'undefined') { 12 setTimeout(initializeOAuth, 100); 13 return; 14 } 15 16 // Load Google Identity Services 17 google.accounts.id.initialize({ 18 client_id: oauthConfig.google.client_id, 19 callback: handleGoogleCredentialResponse 20 }); 21 22 // Render the button 23 google.accounts.id.renderButton( 24 document.querySelector('.google-login'), 25 { theme: 'outline', size: 'large' } 26 ); 27} 28 29// Handle Google credential response 30export async function handleGoogleCredentialResponse(response) { 31 try { 32 // Decode the credential 33 const credential = response.credential; 34 const payload = JSON.parse(atob(credential.split('.')[1])); 35 36 const userData = { 37 id: payload.sub, 38 email: payload.email, 39 name: payload.name 40 }; 41 42 // Update the API endpoint path to match your server configuration 43 dataApiPostOrPut(apiLogInOauth(), { 44 oauth_provider: 'google', 45 oauth_id: userData.id, 46 email: userData.email, 47 name: userData.name 48 }, 'POST') 49 .then(response => { 50 if (!response.ok) { 51 throw new Error(response.statusText); 52 } 53 if (response.status === 409) { 54 handleExistingAccount(response.json()); 55 return; 56 } 57 return response.json(); 58 }) 59 .then(data => { 60 handleSuccessfulLogin(data); 61 }) 62 .catch(error => { 63 showMiniModal("Error", error.message); 64 return; 65 }); 66 } catch (error) { 67 showMiniModal("Error", error.message); 68 return; 69 } 70} 71 72// Handle successful login 73export async function handleSuccessfulLogin(data) { 74 75 // If user can't change username or no username received, redirect to home 76 if (!data.can_change_username || !data.user_name) { 77 showMiniModal("Success", "You have been logged in successfully. Redirecting you in 1 second..."); 78 setTimeout(() => { 79 window.location.href = afterLoginUrl(); 80 }, 1000); 81 return; 82 } 83 84 // Create and show username confirmation dialog 85 const dialogHTML = ` 86 <div class="form-container"> 87 <h3>Welcome!</h3> 88 <p>Your current username is: <strong>${data.user_name}</strong></p> 89 <p>Would you like to keep this username or choose a new one?</p> 90 <div class="form-group username-input" style="display: none;"> 91 <input type="text" id="new-username" class="text-input" placeholder="Enter new username"> 92 <p class="error-message" style="display: none; color: red;"></p> 93 </div> 94 <div class="form-row"> 95 <button id="keep-username" class="button">Keep Username</button> 96 <button id="change-username" class="button">Change Username</button> 97 <button id="submit-username" class="button" style="display: none;">Submit</button> 98 </div> 99 </div> 100 `; 101 102 showModal1({ 103 title: "Please choose a username", 104 content: dialogHTML, 105 closeFunction: null 106 }); 107 108 // Add event listeners 109 document.getElementById('keep-username').addEventListener('click', () => { 110 showMiniModal("Success", "You have been logged in successfully. Redirecting you in 1 second..."); 111 setTimeout(() => { 112 window.location.href = afterLoginUrl(); 113 }, 1000); 114 }); 115 116 document.getElementById('change-username').addEventListener('click', () => { 117 document.querySelector('.username-input').style.display = 'block'; 118 document.getElementById('keep-username').style.display = 'none'; 119 document.getElementById('change-username').style.display = 'none'; 120 document.getElementById('submit-username').style.display = 'block'; 121 }); 122 123 document.getElementById('submit-username').addEventListener('click', async () => { 124 closeModal1(); 125 showMiniModal("Processing username change...", contentLoadingGeneric);
126 const newUsername = document.getElementById('new-username').value.trim(); 127 dataApiPostOrPut(apiSetOauthUsername(), { 128 username: newUsername 129 }, 'POST') 130 .then(response => { 131 return response.json(); 132 }) 133 .then(data => { 134 if (data.error === "Username can only be changed within the first hour of registration") { 135 showMiniModal("Error", "You can only change your username within the first hour of registration."); 136 return; 137 } else if (data.error === "Username already taken") { 138 showMiniModal("Error", "This username is already taken. Please choose another."); 139 return; 140 } else if (data.error === "Invalid username") { 141 showMiniModal("Error", "This username is invalid. Please choose another."); 142 return; 143 } 144 showMiniModal("Success", "Your username has been changed successfully. Redirecting you in 1 second..."); 145 setTimeout(() => { 146 window.location.href = afterLoginUrl(); 147 }, 1000); 148 }) 149 .catch(error => { 150 showMiniModal("Error", error.message); 151 return; 152 }); 153 }); 154} 155 156// Handle existing account error 157export function handleExistingAccount(data) { 158 showMiniModal("Error", "You already have an account with that e-mail. Please log in with it."); 159}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.