add spinner to fix flash of password prompt when auto-decrypting

pull/147/head
robinmoisson 2022-11-20 15:30:48 +01:00
rodzic 4ca89dab35
commit 4950611dc4
2 zmienionych plików z 135 dodań i 62 usunięć

Wyświetl plik

@ -147,18 +147,18 @@
</div>
<div class="form-group">
<label for="title">Passphrase input placeholder</label>
<label for="passphrase_placeholder">Passphrase input placeholder</label>
<input type="text" class="form-control" id="passphrase_placeholder"
placeholder="Default: 'Passphrase'">
</div>
<div class="form-group">
<label for="title">"Remember me" checkbox label</label>
<label for="remember_me">"Remember me" checkbox label</label>
<input type="text" class="form-control" id="remember_me" placeholder="Default: 'Remember me'">
</div>
<div class="form-group">
<label for="title">"Remember me" expiration in days</label>
<label for="remember_in_days">"Remember me" expiration in days</label>
<input type="number"
class="form-control"
id="remember_in_days"
@ -171,7 +171,7 @@
</div>
<div class="form-group">
<label for="title">Decrypt button label</label>
<label for="decrypt_button">Decrypt button label</label>
<input type="text" class="form-control" id="decrypt_button" placeholder="Default: 'DECRYPT'">
</div>

Wyświetl plik

@ -70,6 +70,12 @@
}
.staticrypt-body {
height: 100%;
margin: 0;
}
.staticrypt-content {
height: 100%;
margin-bottom: 1em;
background: #76b852; /* fallback for old browsers */
background: -webkit-linear-gradient(right, #76b852, #8DC26F);
@ -125,41 +131,82 @@
.hidden {
display: none !important;
}
.staticrypt-spinner-container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.staticrypt-spinner {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-bottom;
border: 0.25em solid gray;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: spinner-border .75s linear infinite;
animation: spinner-border .75s linear infinite;
animation-duration: 0.75s;
animation-timing-function: linear;
animation-delay: 0s;
animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: none;
animation-play-state: running;
animation-name: spinner-border;
}
@keyframes spinner-border {
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body class="staticrypt-body">
<div class="staticrypt-page">
<div class="staticrypt-form">
<div class="staticrypt-instructions">
<p class="staticrypt-title">{title}</p>
<p>{instructions}</p>
<div id="staticrypt_loading" class="staticrypt-spinner-container">
<div class="staticrypt-spinner"></div>
</div>
<div id="staticrypt_content" class="staticrypt-content hidden">
<div class="staticrypt-page">
<div class="staticrypt-form">
<div class="staticrypt-instructions">
<p class="staticrypt-title">{title}</p>
<p>{instructions}</p>
</div>
<hr class="staticrypt-hr">
<form id="staticrypt-form" action="#" method="post">
<input id="staticrypt-password"
type="password"
name="password"
placeholder="{passphrase_placeholder}"
autofocus/>
<label id="staticrypt-remember-label" class="staticrypt-remember hidden">
<input id="staticrypt-remember"
type="checkbox"
name="remember"/>
{remember_me}
</label>
<input type="submit" class="staticrypt-decrypt-button" value="{decrypt_button}"/>
</form>
</div>
<hr class="staticrypt-hr">
<form id="staticrypt-form" action="#" method="post">
<input id="staticrypt-password"
type="password"
name="password"
placeholder="{passphrase_placeholder}"
autofocus/>
<label id="staticrypt-remember-label" class="staticrypt-remember hidden">
<input id="staticrypt-remember"
type="checkbox"
name="remember"/>
{remember_me}
</label>
<input type="submit" class="staticrypt-decrypt-button" value="{decrypt_button}"/>
</form>
</div>
<footer class="staticrypt-footer">
<p class="pull-right">Created with <a href="https://robinmoisson.github.io/staticrypt">StatiCrypt</a></p>
</footer>
</div>
<footer class="staticrypt-footer">
<p class="pull-right">Created with <a href="https://robinmoisson.github.io/staticrypt">StatiCrypt</a></p>
</footer>
{crypto_tag}
@ -205,41 +252,67 @@
localStorage.removeItem(rememberExpirationKey);
}
/**
* To be called on load: check if we want to try to decrypt and replace the HTML with the decrypted content, and
* try to do it if needed.
*
* @returns {boolean} true if we derypted and replaced the whole page, false otherwise
*/
function decryptOnLoadFromRememberMe() {
if (!isRememberEnabled) {
return false;
}
// show the remember me checkbox
document.getElementById('staticrypt-remember-label').classList.remove('hidden');
// if we are login out, clear the storage and terminate
var queryParams = new URLSearchParams(window.location.search);
if (queryParams.has("staticrypt_logout")) {
clearLocalStorage();
return false;
}
// if there is expiration configured, check if we're not beyond the expiration
if (rememberDurationInDays && rememberDurationInDays > 0) {
var expiration = localStorage.getItem(rememberExpirationKey),
isExpired = expiration && new Date().getTime() > parseInt(expiration);
if (isExpired) {
clearLocalStorage();
return false;
}
}
var hashedPassphrase = localStorage.getItem(rememberPassphraseKey);
if (hashedPassphrase) {
// try to decrypt
var isDecryptionSuccessful = decryptAndReplaceHtml(hashedPassphrase);
// if the decryption is unsuccessful the password might be wrong - silently clear the saved data and let
// the user fill the password form again
if (!isDecryptionSuccessful) {
clearLocalStorage();
return false;
}
return true;
}
return false;
}
// try to automatically decrypt on load if there is a saved password
window.onload = function () {
if (isRememberEnabled) {
// show the remember me checkbox
document.getElementById('staticrypt-remember-label').classList.remove('hidden');
var hasDecrypted = decryptOnLoadFromRememberMe();
// if we are login out, clear the storage and terminate
var queryParams = new URLSearchParams(window.location.search);
if (queryParams.has("staticrypt_logout")) {
return clearLocalStorage();
}
// if there is expiration configured, check if we're not beyond the expiration
if (rememberDurationInDays && rememberDurationInDays > 0) {
var expiration = localStorage.getItem(rememberExpirationKey),
isExpired = expiration && new Date().getTime() > parseInt(expiration);
if (isExpired) {
return clearLocalStorage();
}
}
var hashedPassphrase = localStorage.getItem(rememberPassphraseKey);
if (hashedPassphrase) {
// try to decrypt
var isDecryptionSuccessful = decryptAndReplaceHtml(hashedPassphrase);
// if the decryption is unsuccessful the password might be wrong - silently clear the saved data and let
// the user fill the password form again
if (!isDecryptionSuccessful) {
return clearLocalStorage();
}
}
// if we didn't decrypt anything, show the password prompt. Otherwise the content has already been replaced, no
// need to do anything
if (!hasDecrypted) {
document.getElementById("staticrypt_loading").classList.add("hidden");
document.getElementById("staticrypt_content").classList.remove("hidden");
}
}