mirror of
https://github.com/dscalzi/HeliosLauncher.git
synced 2024-10-31 19:36:39 -07:00
ec9e95c130
Separate views are stored in an ejs file. When the app starts, each file will be loaded, with the DOM elements hidden. Based on the state of the application, a specific view will be fadded in. Switching between views will use this principle. Moved contents of index.ejs to landing.ejs to make it compatible with the new format. As a result, index.ejs is deprecated and will be removed once it is no longer needed for reference.
267 lines
12 KiB
Plaintext
267 lines
12 KiB
Plaintext
<div id="loginContainer" style="display: none;">
|
|
<div id="loginContent">
|
|
<div id='loginForm'>
|
|
<img id="loginImageSeal" src="assets/images/WesterosSealCircle.png"/>
|
|
<span class="loginSpan" id="loginSubheader">MEMBER LOGIN</span>
|
|
<div class="loginFieldContainer">
|
|
<svg id="profileSVG" class="loginSVG" viewBox="40 37 65.36 61.43">
|
|
<g>
|
|
<path d="M86.77,58.12A13.79,13.79,0,1,0,73,71.91,13.79,13.79,0,0,0,86.77,58.12M97,103.67a3.41,3.41,0,0,0,3.39-3.84,27.57,27.57,0,0,0-54.61,0,3.41,3.41,0,0,0,3.39,3.84Z"/>
|
|
</g>
|
|
</svg>
|
|
<span class="loginErrorSpan" id="loginEmailError">* Invalid Value</span>
|
|
<input id="loginUsername" class="loginField" type="text" placeholder="EMAIL"/>
|
|
</div>
|
|
<div class="loginFieldContainer">
|
|
<svg id="lockSVG" class="loginSVG" viewBox="40 32 60.36 70.43">
|
|
<g>
|
|
<path d="M86.16,54a16.38,16.38,0,1,0-32,0H44V102.7H96V54Zm-25.9-3.39a9.89,9.89,0,1,1,19.77,0A9.78,9.78,0,0,1,79.39,54H60.89A9.78,9.78,0,0,1,60.26,50.59ZM70,96.2a6.5,6.5,0,0,1-6.5-6.5,6.39,6.39,0,0,1,3.1-5.4V67h6.5V84.11a6.42,6.42,0,0,1,3.39,5.6A6.5,6.5,0,0,1,70,96.2Z"/>
|
|
</g>
|
|
</svg>
|
|
<span class="loginErrorSpan" id="loginPasswordError">* Required</span>
|
|
<input id="loginPassword" class="loginField" type="password" placeholder="PASSWORD"/>
|
|
</div>
|
|
<div id="loginOptions">
|
|
<span class="loginSpanDim">
|
|
<a href="https://help.mojang.com/customer/en/portal/articles/329524-change-or-forgot-password">forgot password?</a>
|
|
</span>
|
|
<label id="checkmarkContainer">
|
|
<input id="loginRememberOption" type="checkbox" checked>
|
|
<span id="loginRememberText" class="loginSpanDim">remember me?</span>
|
|
<span class="loginCheckmark"></span>
|
|
</label>
|
|
</div>
|
|
<button id="loginButton" disabled>
|
|
<div id="loginButtonContent">
|
|
LOGIN
|
|
<svg id="loginSVG" viewBox="0 0 24.87 13.97">
|
|
<defs>
|
|
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
|
|
</defs>
|
|
<polyline class="arrowLine" points="0.71 13.26 12.56 1.41 24.16 13.02"/>
|
|
</svg>
|
|
<div class="circle-loader">
|
|
<div class="checkmark draw"></div>
|
|
</div>
|
|
<!--<div class="spinningCircle" id="loginSpinner"></div>-->
|
|
</div>
|
|
</button>
|
|
<div id="loginDisclaimer">
|
|
<span class="loginSpanDim" id="loginRegisterSpan">
|
|
<a href="https://minecraft.net/en-us/store/minecraft/">Need an Account?</a>
|
|
</span>
|
|
<p class="loginDisclaimerText">Your password is sent directly to mojang and never stored.</p>
|
|
<p class="loginDisclaimerText">WesterosCraft is not affiliated with Mojang AB.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="loginErrorContainer">
|
|
<div id="loginErrorContent">
|
|
<span id="loginErrorTitle">LOGIN FAILED:<br>INVALID CREDENTIALS</span>
|
|
<span id="loginErrorDesc">Either the email or password you supplied is invalid. Please ensure everything is correct and try again.</span>
|
|
<button id="loginErrorAcknowledge">Try Again</button>
|
|
</div>
|
|
</div>
|
|
<script type="application/javascript">
|
|
//const validEmail = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
|
|
|
|
// Validation Regexes.
|
|
const validUsername = /^[a-zA-Z0-9_]{1,16}$/
|
|
const basicEmail = /^\S+@\S+\.\S+$/
|
|
|
|
// DOM cache.
|
|
const loginContainer = document.getElementById('loginContainer')
|
|
const loginErrorTitle = document.getElementById('loginErrorTitle')
|
|
const loginErrorDesc = document.getElementById('loginErrorDesc')
|
|
const loginErrorAcknowledge = document.getElementById('loginErrorAcknowledge')
|
|
|
|
const loginEmailError = document.getElementById('loginEmailError')
|
|
const loginUsername = document.getElementById('loginUsername')
|
|
const loginPasswordError = document.getElementById('loginPasswordError')
|
|
const loginPassword = document.getElementById('loginPassword')
|
|
const checkmarkContainer = document.getElementById('checkmarkContainer')
|
|
const loginRememberOption = document.getElementById('loginRememberOption')
|
|
const loginButton = document.getElementById('loginButton')
|
|
|
|
// Control variables.
|
|
let lu = false, lp = false
|
|
|
|
// Show error element.
|
|
function showError(element, value){
|
|
element.innerHTML = value
|
|
element.style.opacity = 1
|
|
}
|
|
|
|
// Shake error element.
|
|
function shakeError(element){
|
|
if(element.style.opacity == 1){
|
|
element.classList.remove('shake')
|
|
void element.offsetWidth
|
|
element.classList.add('shake')
|
|
}
|
|
}
|
|
|
|
// Validate email field is neither empty nor invalid.
|
|
function validateEmail(value){
|
|
if(value){
|
|
if(!basicEmail.test(value) && !validUsername.test(value)){
|
|
showError(loginEmailError, '* Invalid Value')
|
|
loginDisabled(true)
|
|
lu = false
|
|
} else {
|
|
loginEmailError.style.opacity = 0
|
|
lu = true
|
|
if(lp){
|
|
loginDisabled(false)
|
|
}
|
|
}
|
|
} else {
|
|
lu = false
|
|
showError(loginEmailError, '* Required')
|
|
loginDisabled(true)
|
|
}
|
|
}
|
|
|
|
// Validate password field is not empty.
|
|
function validatePassword(value){
|
|
if(value){
|
|
loginPasswordError.style.opacity = 0
|
|
lp = true
|
|
if(lu){
|
|
loginDisabled(false)
|
|
}
|
|
} else {
|
|
lp = false
|
|
showError(loginPasswordError, '* Required')
|
|
loginDisabled(true)
|
|
}
|
|
}
|
|
|
|
// Emphasize errors with shake when focus is lost.
|
|
loginUsername.addEventListener('focusout', (e) => {
|
|
validateEmail(e.target.value)
|
|
shakeError(loginEmailError)
|
|
})
|
|
loginPassword.addEventListener('focusout', (e) => {
|
|
validatePassword(e.target.value)
|
|
shakeError(loginPasswordError)
|
|
})
|
|
|
|
// Validate input for each field.
|
|
loginUsername.addEventListener('input', (e) => {
|
|
validateEmail(e.target.value)
|
|
})
|
|
loginPassword.addEventListener('input', (e) => {
|
|
validatePassword(e.target.value)
|
|
})
|
|
|
|
// Enable or disable login button.
|
|
function loginDisabled(v){
|
|
if(loginButton.disabled !== v){
|
|
loginButton.disabled = v
|
|
}
|
|
}
|
|
|
|
// Enable or disable loading elements.
|
|
function loginLoading(v){
|
|
if(v){
|
|
loginButton.setAttribute('loading', v)
|
|
loginButton.innerHTML = loginButton.innerHTML.replace('LOGIN', 'LOGGING IN')
|
|
} else {
|
|
loginButton.removeAttribute('loading')
|
|
loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'LOGIN')
|
|
}
|
|
}
|
|
|
|
// Disable or enable login form.
|
|
function formDisabled(v){
|
|
loginDisabled(v)
|
|
loginUsername.disabled = v
|
|
loginPassword.disabled = v
|
|
if(v){
|
|
checkmarkContainer.setAttribute('disabled', v)
|
|
} else {
|
|
checkmarkContainer.removeAttribute('disabled')
|
|
}
|
|
loginRememberOption.disabled = v
|
|
}
|
|
|
|
function resolveError(err){
|
|
if(err.cause != null && err.cause === 'UserMigratedException') {
|
|
return {
|
|
title: 'Error During Login:<br>Invalid Credentials',
|
|
desc: 'You\'ve attempted to login with a migrated account. Try again using the account email as the username.'
|
|
}
|
|
} else {
|
|
if(err.error != null){
|
|
if(err.error === 'ForbiddenOperationException'){
|
|
if(err.errorMessage != null){
|
|
if(err.errorMessage === 'Invalid credentials. Invalid username or password.'){
|
|
return {
|
|
title: 'Error During Login:<br>Invalid Credentials',
|
|
desc: 'The email or password you\'ve entered is incorrect. Please try again.'
|
|
}
|
|
} else if(err.errorMessage === 'Invalid credentials.'){
|
|
return {
|
|
title: 'Error During Login:<br>Too Many Attempts',
|
|
desc: 'There have been too many login attempts with this account recently. Please try again later.'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
title: err.error,
|
|
desc: err.errorMessage
|
|
}
|
|
}
|
|
|
|
loginButton.addEventListener('click', () => {
|
|
// Disable form.
|
|
formDisabled(true)
|
|
|
|
// Show loading stuff.
|
|
loginLoading(true)
|
|
|
|
AuthManager.addAccount(loginUsername.value, loginPassword.value).then((value) => {
|
|
loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'SUCCESS')
|
|
$('.circle-loader').toggleClass('load-complete')
|
|
$('.checkmark').toggle()
|
|
console.log(value)
|
|
}).catch((err) => {
|
|
loginLoading(false)
|
|
$('#loginErrorContainer').css('display', 'flex').hide().fadeIn(250)
|
|
loginContainer.setAttribute('error', true)
|
|
const errF = resolveError(err)
|
|
loginErrorTitle.innerHTML = errF.title
|
|
loginErrorDesc.innerHTML = errF.desc
|
|
console.log(err)
|
|
})
|
|
|
|
// Temp for debugging, use procedure with real code.
|
|
setTimeout(() => {
|
|
loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'SUCCESS')
|
|
$('.circle-loader').toggleClass('load-complete')
|
|
$('.checkmark').toggle()
|
|
}, 2500)
|
|
|
|
})
|
|
|
|
loginErrorAcknowledge.addEventListener('click', () => {
|
|
formDisabled(false)
|
|
loginContainer.removeAttribute('error', false)
|
|
$('#loginErrorContainer').fadeOut(250)
|
|
})
|
|
</script>
|
|
<!-- Will reuse this down the line, then it will be removed from this file. -->
|
|
<!--<div id="loginLoading">
|
|
<div id="loginLoadingContent">
|
|
<div id="loadSpinnerContainer">
|
|
<img id="loadCenterImage" src="assets/images/westeroscraftlogo1.png">
|
|
<img id="loadSpinnerImage" class="rotating" src="assets/images/westeroscraftlogo2.png">
|
|
</div>
|
|
<span id="loadDescText">LOGGING IN</span>
|
|
</div>
|
|
</div>-->
|
|
</div> |