use URL fragment for logout/auto-decrypt (closes #156)

v2 v2.6.0
robinmoisson 2023-03-29 11:49:10 +02:00
rodzic cc37c5c70d
commit 228af74a61
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 9419716500078583
8 zmienionych plików z 89 dodań i 27 usunięć

Wyświetl plik

@ -42,9 +42,9 @@ staticrypt test.html --engine webcrypto
**Encrypt a file and get a shareable link containing the hashed password** - you can include your file URL or leave blank:
```bash
# you can also pass '--share' without specifying the URL to get the `?staticrypt_pwd=...`
# you can also pass '--share' without specifying the URL to get the `#staticrypt_pwd=...`
staticrypt test.html MY_LONG_PASSWORD --share https://example.com/test_encrypted.html --engine webcrypto
# => https://example.com/test_encrypted.html?staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f
# => https://example.com/test_encrypted.html#staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f
```
**Encrypt all html files in a directory** and replace them with encrypted versions (`{}` will be replaced with each file name by the `find` command - if you wanted to move the encrypted files to an `encrypted/` directory, you could use `-o encrypted/{}`):
@ -106,7 +106,7 @@ The password argument is optional if `STATICRYPT_PASSWORD` is set in the environ
you can use: "statycrypt -s". [string]
--share Get a link containing your hashed password that
will auto-decrypt the page. Pass your URL as a
value to append "?staticrypt_pwd=<hashed_pwd>",
value to append "#staticrypt_pwd=<hashed_pwd>",
or leave empty to display the hash to append.
[string]
--short Hide the "short password" warning.
@ -175,7 +175,7 @@ If no value is provided the stored password doesn't expire, you can also give it
#### "Logging out"
You can clear StatiCrypt values in localStorage (effectively "logging out") at any time by appending `staticrypt_logout` to the URL query parameters (`mysite.com?staticrypt_logout`).
You can clear StatiCrypt values in localStorage (effectively "logging out") at any time by appending `staticrypt_logout` to the URL fragment (`mysite.com#staticrypt_logout`).
#### Encrypting multiple pages

Wyświetl plik

@ -297,7 +297,7 @@ function parseCommandLineArguments() {
.option("share", {
describe:
'Get a link containing your hashed password that will auto-decrypt the page. Pass your URL as a value to append '
+ '"?staticrypt_pwd=<hashed_pwd>", or leave empty to display the hash to append.',
+ '"#staticrypt_pwd=<hashed_pwd>", or leave empty to display the hash to append.',
type: "string",
})
.option("short", {

Wyświetl plik

@ -88,7 +88,7 @@ async function runStatiCrypt() {
const hashedPassword = await cryptoEngine.hashPassphrase(password, salt);
console.log(url + "?staticrypt_pwd=" + hashedPassword);
console.log(url + "#staticrypt_pwd=" + hashedPassword);
}
// TODO: remove in the next major version bump. This is to allow a security update to some versions without breaking

Wyświetl plik

@ -564,7 +564,7 @@ exports.init = init;
const decode = codec.init(cryptoEngine).decode;
// variables to be filled when generating the file
const encryptedMsg = '1c9cbdfdb99a165b6459b329f37250ec99c30c53c5cca71d28e19314268896ec613dc0443a36e38dc5a983145dda064fc7716024e87c32ae5dbe03a888731e53e0869a0e739134d91fb343c0b11c759a2a9f9ac755544274af0fad8959919ad91e285405f9255b9ad8ce83f3f8e13e367c0b061b1bd84df78440a63196469743d34a887819d31111750f0de9d915e85020ca3b4cd209e5ad82678c572fc677642a8884fff4943b6366d4172d515519db96b6476f23066d36ae40b1b3bdd3c69a',
const encryptedMsg = 'df7428ed075decd3c4ff9d8ab6d2bea4410854c863d705789fb22e14b7da7ee20e94c593047abb9ba34d6519eebc879d2097bb918c0af0d4e248959849fb9c6bbb93aba054806c8773d1e4b63ec317185ad5462a9919dda986716c67bb57a89a044de3e25707cded482657c4a0208e9916aaa9d839f090eaaeb95603e05db11fe4bc37c4d98b9170124ce1c7ca18fe39c2f179e23eee61ba7d79cb3145e8833936c62adeffce1f5e129745c89541faa8100bfde4733bfa9c0ecf04768b3d1889',
salt = 'b93bbaf35459951c47721d1f3eaeb5b9',
labelError = 'Bad password!',
isRememberEnabled = true,
@ -600,6 +600,31 @@ exports.init = init;
localStorage.removeItem(rememberExpirationKey);
}
/**
* Clear storage if we are logging out
*
* @returns - whether we logged out
*/
function logoutIfNeeded() {
const logoutKey = "staticrypt_logout";
// handle logout through query param
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.has(logoutKey)) {
clearLocalStorage();
return true;
}
// handle logout through URL fragment
const hash = window.location.hash.substring(1);
if (hash.includes(logoutKey)) {
clearLocalStorage();
return true;
}
return false;
}
/**
* 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.
@ -614,11 +639,8 @@ exports.init = init;
// show the remember me checkbox
document.getElementById('staticrypt-remember-label').classList.remove('hidden');
// if we are login out, clear the storage and terminate
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.has("staticrypt_logout")) {
clearLocalStorage();
// if we are login out, terminate
if (logoutIfNeeded()) {
return false;
}
@ -652,9 +674,18 @@ exports.init = init;
return false;
}
function decryptOnLoadFromQueryParam() {
function decryptOnLoadFromUrl() {
const passwordKey = "staticrypt_pwd";
// get the password from the query param
const queryParams = new URLSearchParams(window.location.search);
const hashedPassphrase = queryParams.get("staticrypt_pwd");
const hashedPassphraseQuery = queryParams.get(passwordKey);
// get the password from the url fragment
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
const hashedPassphraseFragment = hashRegexMatch ? hashRegexMatch[1] : null;
const hashedPassphrase = hashedPassphraseFragment || hashedPassphraseQuery;
if (hashedPassphrase) {
return decryptAndReplaceHtml(hashedPassphrase);
@ -665,7 +696,7 @@ exports.init = init;
// try to automatically decrypt on load if there is a saved password
window.onload = async function () {
let hasDecrypted = await decryptOnLoadFromQueryParam();
let hasDecrypted = await decryptOnLoadFromUrl();
if (!hasDecrypted) {
hasDecrypted = await decryptOnLoadFromRememberMe();

Wyświetl plik

@ -112,7 +112,7 @@
<div class="form-group">
<label class="no-style">
<input type="checkbox" id="remember" checked>
Add "Remember me" checkbox (append <code>?staticrypt_logout</code> to your URL to logout)
Add "Remember me" checkbox (append <code>#staticrypt_logout</code> to your URL to logout)
<small>
<abbr class="text-muted"
title="The password will be stored in clear text in the browser's localStorage upon entry by the user. See &quot;More options&quot; to set the expiration (default: none)">
@ -616,7 +616,7 @@ exports.renderTemplate = renderTemplate;
/**
* Register something happened - this uses a simple Supabase function to implement a counter, and allows use to drop
* google analytics. We don't store the IP or any personal information.
* google analytics.
*
* @param action
*/

Wyświetl plik

@ -231,6 +231,31 @@
localStorage.removeItem(rememberExpirationKey);
}
/**
* Clear storage if we are logging out
*
* @returns {boolean} - whether we logged out
*/
function logoutIfNeeded() {
const logoutKey = "staticrypt_logout";
// handle logout through query param
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.has(logoutKey)) {
clearLocalStorage();
return true;
}
// handle logout through URL fragment
const hash = window.location.hash.substring(1);
if (hash.includes(logoutKey)) {
clearLocalStorage();
return true;
}
return false;
}
/**
* 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.
@ -245,11 +270,8 @@
// show the remember me checkbox
document.getElementById('staticrypt-remember-label').classList.remove('hidden');
// if we are login out, clear the storage and terminate
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.has("staticrypt_logout")) {
clearLocalStorage();
// if we are login out, terminate
if (logoutIfNeeded()) {
return false;
}
@ -283,9 +305,18 @@
return false;
}
function decryptOnLoadFromQueryParam() {
function decryptOnLoadFromUrl() {
const passwordKey = "staticrypt_pwd";
// get the password from the query param
const queryParams = new URLSearchParams(window.location.search);
const hashedPassphrase = queryParams.get("staticrypt_pwd");
const hashedPassphraseQuery = queryParams.get(passwordKey);
// get the password from the url fragment
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
const hashedPassphraseFragment = hashRegexMatch ? hashRegexMatch[1] : null;
const hashedPassphrase = hashedPassphraseFragment || hashedPassphraseQuery;
if (hashedPassphrase) {
return decryptAndReplaceHtml(hashedPassphrase);
@ -296,7 +327,7 @@
// try to automatically decrypt on load if there is a saved password
window.onload = async function () {
let hasDecrypted = await decryptOnLoadFromQueryParam();
let hasDecrypted = await decryptOnLoadFromUrl();
if (!hasDecrypted) {
hasDecrypted = await decryptOnLoadFromRememberMe();

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "staticrypt",
"version": "2.5.0",
"version": "2.6.0",
"description": "Based on the [crypto-js](https://github.com/brix/crypto-js) library, StatiCrypt uses AES-256 to encrypt your input with your passphrase and put it in a HTML file with a password prompt that can decrypted in-browser (client side).",
"main": "index.js",
"files": [

Wyświetl plik

@ -112,7 +112,7 @@
<div class="form-group">
<label class="no-style">
<input type="checkbox" id="remember" checked>
Add "Remember me" checkbox (append <code>?staticrypt_logout</code> to your URL to logout)
Add "Remember me" checkbox (append <code>#staticrypt_logout</code> to your URL to logout)
<small>
<abbr class="text-muted"
title="The password will be stored in clear text in the browser's localStorage upon entry by the user. See &quot;More options&quot; to set the expiration (default: none)">