add --share-remember to remember the password in shared links

closes #183, closes #184. Thank you @uzadude!
main
robinmoisson 2024-02-13 21:58:59 +01:00
rodzic 2a44c5973d
commit 1e5e6cf7dd
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 9419716500078583
7 zmienionych plików z 81 dodań i 28 usunięć

Wyświetl plik

@ -78,6 +78,11 @@ staticrypt dir_to_encrypt/* -r -d dir_to_encrypt
# you can also pass '--share' without specifying the URL to get the `#staticrypt_pwd=...`
staticrypt test.html --share https://example.com/encrypted.html
# => https://example.com/encrypted.html#staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f
# add --share-remember to auto-enable "Remember-me" - useful if you want send one link to autodecrypt multiple pages
# (you can also just append '&remember_me')
staticrypt test.html --share --share-remember
# => #staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f&remember_me
```
**Pin the salt to use staticrypt in your CI in a build step** - if you want want the "Remember-me" or share features to work accross multiple pages or multiple successive deployment, the salt needs to stay the same ([see why](https://github.com/robinmoisson/staticrypt#why-does-staticrypt-create-a-config-file)). If you run StatiCrypt in a CI step, you can pin the salt in two ways:
@ -152,6 +157,8 @@ The password argument is optional if `STATICRYPT_PASSWORD` is set in the environ
as a value to append
"#staticrypt_pwd=<hashed_pwd>", or leave empty
to display the hash to append. [string]
--share-remember Whether the share link should auto-enable
'Remember-me'. [boolean] [default: false]
--short Hide the "short password" warning.
[boolean] [default: false]
-t, --template Path to custom HTML template with password

Wyświetl plik

@ -426,6 +426,11 @@ function parseCommandLineArguments() {
'"#staticrypt_pwd=<hashed_pwd>", or leave empty to display the hash to append.',
type: "string",
})
.option("share-remember", {
type: "boolean",
describe: "Whether the share link should auto-enable 'Remember-me'.",
default: false,
})
.option("short", {
describe: 'Hide the "short password" warning.',
type: "boolean",

Wyświetl plik

@ -86,9 +86,14 @@ async function runStatiCrypt() {
if (hasShareFlag) {
await validatePassword(password, namedArgs.short);
const url = namedArgs.share || "";
let url = namedArgs.share || "";
url += "#staticrypt_pwd=" + hashedPassword;
console.log(url + "#staticrypt_pwd=" + hashedPassword);
if (namedArgs.shareRemember) {
url += `&remember_me`;
}
console.log(url);
return;
}

Wyświetl plik

@ -610,11 +610,17 @@ function init(staticryptConfig, templateConfig) {
* expose more information in the future we can do it without breaking the password_template
*/
async function handleDecryptionOfPage(password, isRememberChecked) {
const { isRememberEnabled, rememberDurationInDays, staticryptSaltUniqueVariableName } = staticryptConfig;
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
const { staticryptSaltUniqueVariableName } = staticryptConfig;
// decrypt and replace the whole page
const hashedPassword = await cryptoEngine.hashPassword(password, staticryptSaltUniqueVariableName);
return handleDecryptionOfPageFromHash(hashedPassword, isRememberChecked);
}
exports.handleDecryptionOfPage = handleDecryptionOfPage;
async function handleDecryptionOfPageFromHash(hashedPassword, isRememberChecked) {
const { isRememberEnabled, rememberDurationInDays } = staticryptConfig;
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
const isDecryptionSuccessful = await decryptAndReplaceHtml(hashedPassword);
@ -643,7 +649,7 @@ function init(staticryptConfig, templateConfig) {
hashedPassword,
};
}
exports.handleDecryptionOfPage = handleDecryptionOfPage;
exports.handleDecryptionOfPageFromHash = handleDecryptionOfPageFromHash;
/**
* Clear localstorage from staticrypt related values
@ -740,21 +746,27 @@ function init(staticryptConfig, templateConfig) {
return false;
}
function decryptOnLoadFromUrl() {
async function decryptOnLoadFromUrl() {
const passwordKey = "staticrypt_pwd";
const rememberMeKey = "remember_me";
// get the password from the query param
// try to get the password from the query param (for backward compatibility - we now want to avoid this method,
// since it sends the hashed password to the server which isn't needed)
const queryParams = new URLSearchParams(window.location.search);
const hashedPasswordQuery = queryParams.get(passwordKey);
const rememberMeQuery = queryParams.get(rememberMeKey);
const urlFragment = window.location.hash.substring(1);
// get the password from the url fragment
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
const hashedPasswordFragment = hashRegexMatch ? hashRegexMatch[1] : null;
const hashedPasswordRegexMatch = urlFragment.match(new RegExp(passwordKey + "=([^&]*)"));
const hashedPasswordFragment = hashedPasswordRegexMatch ? hashedPasswordRegexMatch[1] : null;
const rememberMeFragment = urlFragment.includes(rememberMeKey);
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
const rememberMe = rememberMeFragment || rememberMeQuery;
if (hashedPassword) {
return decryptAndReplaceHtml(hashedPassword);
return handleDecryptionOfPageFromHash(hashedPassword, rememberMe);
}
return false;
@ -768,7 +780,7 @@ exports.init = init;
})());
const templateError = "Bad password!",
isRememberEnabled = true,
staticryptConfig = {"staticryptEncryptedMsgUniqueVariableName":"da67de28fb1fec9f04aaf615aa0e80a9675a43473e21b51a1dee72cb6153728dde06e9c242c6de08ab4608d18e73c9f922466a4695fe60e8f684f7d5d7b54149d7749bc2e626e39844d6757289f17696ea7992d1c87b49f76903c57d6506bb5aee0f0cdf4183bb20f71ad0f719c5a3ee338a486c70a1d433c00fd4384c2ec65471c436dc4cf0c4ba13a2189db1ee335f113652439c1feb2c02bf237ddada4ae46bd404f3f8417cc6b27d2e7960024afe2323edb19e8f38c699b9f4ce0db36d37","isRememberEnabled":true,"rememberDurationInDays":0,"staticryptSaltUniqueVariableName":"b93bbaf35459951c47721d1f3eaeb5b9"};
staticryptConfig = {"staticryptEncryptedMsgUniqueVariableName":"0aebc39457f31c757cef31f0fa9b2fb0cb4ebe9845a3690ab119002ae21ce5b7b200ded81ad6da56d0f6b98df029102c0913440135cd3f75b84f481ee32aab034c0bb3055168d6c49afd4b59e7189b539b573e6effbd29e403ef3234ab8bd1c2de1cd97a4f94e88c4d632f8648e9d99c7d988723634ce805d021d1d017c3e125e98e58914db31c4cca5a0f6b1f4464d284a48548a1eb5edad8f910aea4d2beee6b811785b556c7ec67c48112f551aa860614faf34887267c6119feda894b3ed8","isRememberEnabled":true,"rememberDurationInDays":0,"staticryptSaltUniqueVariableName":"b93bbaf35459951c47721d1f3eaeb5b9"};
// you can edit these values to customize some of the behavior of StatiCrypt
const templateConfig = {

Wyświetl plik

@ -1101,11 +1101,17 @@ function init(staticryptConfig, templateConfig) {
* expose more information in the future we can do it without breaking the password_template
*/
async function handleDecryptionOfPage(password, isRememberChecked) {
const { isRememberEnabled, rememberDurationInDays, staticryptSaltUniqueVariableName } = staticryptConfig;
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
const { staticryptSaltUniqueVariableName } = staticryptConfig;
// decrypt and replace the whole page
const hashedPassword = await cryptoEngine.hashPassword(password, staticryptSaltUniqueVariableName);
return handleDecryptionOfPageFromHash(hashedPassword, isRememberChecked);
}
exports.handleDecryptionOfPage = handleDecryptionOfPage;
async function handleDecryptionOfPageFromHash(hashedPassword, isRememberChecked) {
const { isRememberEnabled, rememberDurationInDays } = staticryptConfig;
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
const isDecryptionSuccessful = await decryptAndReplaceHtml(hashedPassword);
@ -1134,7 +1140,7 @@ function init(staticryptConfig, templateConfig) {
hashedPassword,
};
}
exports.handleDecryptionOfPage = handleDecryptionOfPage;
exports.handleDecryptionOfPageFromHash = handleDecryptionOfPageFromHash;
/**
* Clear localstorage from staticrypt related values
@ -1231,21 +1237,27 @@ function init(staticryptConfig, templateConfig) {
return false;
}
function decryptOnLoadFromUrl() {
async function decryptOnLoadFromUrl() {
const passwordKey = "staticrypt_pwd";
const rememberMeKey = "remember_me";
// get the password from the query param
// try to get the password from the query param (for backward compatibility - we now want to avoid this method,
// since it sends the hashed password to the server which isn't needed)
const queryParams = new URLSearchParams(window.location.search);
const hashedPasswordQuery = queryParams.get(passwordKey);
const rememberMeQuery = queryParams.get(rememberMeKey);
const urlFragment = window.location.hash.substring(1);
// get the password from the url fragment
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
const hashedPasswordFragment = hashRegexMatch ? hashRegexMatch[1] : null;
const hashedPasswordRegexMatch = urlFragment.match(new RegExp(passwordKey + "=([^&]*)"));
const hashedPasswordFragment = hashedPasswordRegexMatch ? hashedPasswordRegexMatch[1] : null;
const rememberMeFragment = urlFragment.includes(rememberMeKey);
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
const rememberMe = rememberMeFragment || rememberMeQuery;
if (hashedPassword) {
return decryptAndReplaceHtml(hashedPassword);
return handleDecryptionOfPageFromHash(hashedPassword, rememberMe);
}
return false;

Wyświetl plik

@ -63,11 +63,17 @@ function init(staticryptConfig, templateConfig) {
* expose more information in the future we can do it without breaking the password_template
*/
async function handleDecryptionOfPage(password, isRememberChecked) {
const { isRememberEnabled, rememberDurationInDays, staticryptSaltUniqueVariableName } = staticryptConfig;
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
const { staticryptSaltUniqueVariableName } = staticryptConfig;
// decrypt and replace the whole page
const hashedPassword = await cryptoEngine.hashPassword(password, staticryptSaltUniqueVariableName);
return handleDecryptionOfPageFromHash(hashedPassword, isRememberChecked);
}
exports.handleDecryptionOfPage = handleDecryptionOfPage;
async function handleDecryptionOfPageFromHash(hashedPassword, isRememberChecked) {
const { isRememberEnabled, rememberDurationInDays } = staticryptConfig;
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
const isDecryptionSuccessful = await decryptAndReplaceHtml(hashedPassword);
@ -96,7 +102,7 @@ function init(staticryptConfig, templateConfig) {
hashedPassword,
};
}
exports.handleDecryptionOfPage = handleDecryptionOfPage;
exports.handleDecryptionOfPageFromHash = handleDecryptionOfPageFromHash;
/**
* Clear localstorage from staticrypt related values
@ -193,21 +199,27 @@ function init(staticryptConfig, templateConfig) {
return false;
}
function decryptOnLoadFromUrl() {
async function decryptOnLoadFromUrl() {
const passwordKey = "staticrypt_pwd";
const rememberMeKey = "remember_me";
// get the password from the query param
// try to get the password from the query param (for backward compatibility - we now want to avoid this method,
// since it sends the hashed password to the server which isn't needed)
const queryParams = new URLSearchParams(window.location.search);
const hashedPasswordQuery = queryParams.get(passwordKey);
const rememberMeQuery = queryParams.get(rememberMeKey);
const urlFragment = window.location.hash.substring(1);
// get the password from the url fragment
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
const hashedPasswordFragment = hashRegexMatch ? hashRegexMatch[1] : null;
const hashedPasswordRegexMatch = urlFragment.match(new RegExp(passwordKey + "=([^&]*)"));
const hashedPasswordFragment = hashedPasswordRegexMatch ? hashedPasswordRegexMatch[1] : null;
const rememberMeFragment = urlFragment.includes(rememberMeKey);
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
const rememberMe = rememberMeFragment || rememberMeQuery;
if (hashedPassword) {
return decryptAndReplaceHtml(hashedPassword);
return handleDecryptionOfPageFromHash(hashedPassword, rememberMe);
}
return false;

Wyświetl plik

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