kopia lustrzana https://github.com/robinmoisson/staticrypt
add --share-remember to remember the password in shared links
closes #183, closes #184. Thank you @uzadude!main
rodzic
2a44c5973d
commit
1e5e6cf7dd
|
@ -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=...`
|
# you can also pass '--share' without specifying the URL to get the `#staticrypt_pwd=...`
|
||||||
staticrypt test.html --share https://example.com/encrypted.html
|
staticrypt test.html --share https://example.com/encrypted.html
|
||||||
# => https://example.com/encrypted.html#staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f
|
# => 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:
|
**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
|
as a value to append
|
||||||
"#staticrypt_pwd=<hashed_pwd>", or leave empty
|
"#staticrypt_pwd=<hashed_pwd>", or leave empty
|
||||||
to display the hash to append. [string]
|
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.
|
--short Hide the "short password" warning.
|
||||||
[boolean] [default: false]
|
[boolean] [default: false]
|
||||||
-t, --template Path to custom HTML template with password
|
-t, --template Path to custom HTML template with password
|
||||||
|
|
|
@ -426,6 +426,11 @@ function parseCommandLineArguments() {
|
||||||
'"#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",
|
type: "string",
|
||||||
})
|
})
|
||||||
|
.option("share-remember", {
|
||||||
|
type: "boolean",
|
||||||
|
describe: "Whether the share link should auto-enable 'Remember-me'.",
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
.option("short", {
|
.option("short", {
|
||||||
describe: 'Hide the "short password" warning.',
|
describe: 'Hide the "short password" warning.',
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
|
|
|
@ -86,9 +86,14 @@ async function runStatiCrypt() {
|
||||||
if (hasShareFlag) {
|
if (hasShareFlag) {
|
||||||
await validatePassword(password, namedArgs.short);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -610,11 +610,17 @@ function init(staticryptConfig, templateConfig) {
|
||||||
* expose more information in the future we can do it without breaking the password_template
|
* expose more information in the future we can do it without breaking the password_template
|
||||||
*/
|
*/
|
||||||
async function handleDecryptionOfPage(password, isRememberChecked) {
|
async function handleDecryptionOfPage(password, isRememberChecked) {
|
||||||
const { isRememberEnabled, rememberDurationInDays, staticryptSaltUniqueVariableName } = staticryptConfig;
|
const { staticryptSaltUniqueVariableName } = staticryptConfig;
|
||||||
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
|
|
||||||
|
|
||||||
// decrypt and replace the whole page
|
// decrypt and replace the whole page
|
||||||
const hashedPassword = await cryptoEngine.hashPassword(password, staticryptSaltUniqueVariableName);
|
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);
|
const isDecryptionSuccessful = await decryptAndReplaceHtml(hashedPassword);
|
||||||
|
|
||||||
|
@ -643,7 +649,7 @@ function init(staticryptConfig, templateConfig) {
|
||||||
hashedPassword,
|
hashedPassword,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.handleDecryptionOfPage = handleDecryptionOfPage;
|
exports.handleDecryptionOfPageFromHash = handleDecryptionOfPageFromHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear localstorage from staticrypt related values
|
* Clear localstorage from staticrypt related values
|
||||||
|
@ -740,21 +746,27 @@ function init(staticryptConfig, templateConfig) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptOnLoadFromUrl() {
|
async function decryptOnLoadFromUrl() {
|
||||||
const passwordKey = "staticrypt_pwd";
|
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 queryParams = new URLSearchParams(window.location.search);
|
||||||
const hashedPasswordQuery = queryParams.get(passwordKey);
|
const hashedPasswordQuery = queryParams.get(passwordKey);
|
||||||
|
const rememberMeQuery = queryParams.get(rememberMeKey);
|
||||||
|
|
||||||
|
const urlFragment = window.location.hash.substring(1);
|
||||||
// get the password from the url fragment
|
// get the password from the url fragment
|
||||||
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
|
const hashedPasswordRegexMatch = urlFragment.match(new RegExp(passwordKey + "=([^&]*)"));
|
||||||
const hashedPasswordFragment = hashRegexMatch ? hashRegexMatch[1] : null;
|
const hashedPasswordFragment = hashedPasswordRegexMatch ? hashedPasswordRegexMatch[1] : null;
|
||||||
|
const rememberMeFragment = urlFragment.includes(rememberMeKey);
|
||||||
|
|
||||||
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
|
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
|
||||||
|
const rememberMe = rememberMeFragment || rememberMeQuery;
|
||||||
|
|
||||||
if (hashedPassword) {
|
if (hashedPassword) {
|
||||||
return decryptAndReplaceHtml(hashedPassword);
|
return handleDecryptionOfPageFromHash(hashedPassword, rememberMe);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -768,7 +780,7 @@ exports.init = init;
|
||||||
})());
|
})());
|
||||||
const templateError = "Bad password!",
|
const templateError = "Bad password!",
|
||||||
isRememberEnabled = true,
|
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
|
// you can edit these values to customize some of the behavior of StatiCrypt
|
||||||
const templateConfig = {
|
const templateConfig = {
|
||||||
|
|
28
index.html
28
index.html
|
@ -1101,11 +1101,17 @@ function init(staticryptConfig, templateConfig) {
|
||||||
* expose more information in the future we can do it without breaking the password_template
|
* expose more information in the future we can do it without breaking the password_template
|
||||||
*/
|
*/
|
||||||
async function handleDecryptionOfPage(password, isRememberChecked) {
|
async function handleDecryptionOfPage(password, isRememberChecked) {
|
||||||
const { isRememberEnabled, rememberDurationInDays, staticryptSaltUniqueVariableName } = staticryptConfig;
|
const { staticryptSaltUniqueVariableName } = staticryptConfig;
|
||||||
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
|
|
||||||
|
|
||||||
// decrypt and replace the whole page
|
// decrypt and replace the whole page
|
||||||
const hashedPassword = await cryptoEngine.hashPassword(password, staticryptSaltUniqueVariableName);
|
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);
|
const isDecryptionSuccessful = await decryptAndReplaceHtml(hashedPassword);
|
||||||
|
|
||||||
|
@ -1134,7 +1140,7 @@ function init(staticryptConfig, templateConfig) {
|
||||||
hashedPassword,
|
hashedPassword,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.handleDecryptionOfPage = handleDecryptionOfPage;
|
exports.handleDecryptionOfPageFromHash = handleDecryptionOfPageFromHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear localstorage from staticrypt related values
|
* Clear localstorage from staticrypt related values
|
||||||
|
@ -1231,21 +1237,27 @@ function init(staticryptConfig, templateConfig) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptOnLoadFromUrl() {
|
async function decryptOnLoadFromUrl() {
|
||||||
const passwordKey = "staticrypt_pwd";
|
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 queryParams = new URLSearchParams(window.location.search);
|
||||||
const hashedPasswordQuery = queryParams.get(passwordKey);
|
const hashedPasswordQuery = queryParams.get(passwordKey);
|
||||||
|
const rememberMeQuery = queryParams.get(rememberMeKey);
|
||||||
|
|
||||||
|
const urlFragment = window.location.hash.substring(1);
|
||||||
// get the password from the url fragment
|
// get the password from the url fragment
|
||||||
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
|
const hashedPasswordRegexMatch = urlFragment.match(new RegExp(passwordKey + "=([^&]*)"));
|
||||||
const hashedPasswordFragment = hashRegexMatch ? hashRegexMatch[1] : null;
|
const hashedPasswordFragment = hashedPasswordRegexMatch ? hashedPasswordRegexMatch[1] : null;
|
||||||
|
const rememberMeFragment = urlFragment.includes(rememberMeKey);
|
||||||
|
|
||||||
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
|
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
|
||||||
|
const rememberMe = rememberMeFragment || rememberMeQuery;
|
||||||
|
|
||||||
if (hashedPassword) {
|
if (hashedPassword) {
|
||||||
return decryptAndReplaceHtml(hashedPassword);
|
return handleDecryptionOfPageFromHash(hashedPassword, rememberMe);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -63,11 +63,17 @@ function init(staticryptConfig, templateConfig) {
|
||||||
* expose more information in the future we can do it without breaking the password_template
|
* expose more information in the future we can do it without breaking the password_template
|
||||||
*/
|
*/
|
||||||
async function handleDecryptionOfPage(password, isRememberChecked) {
|
async function handleDecryptionOfPage(password, isRememberChecked) {
|
||||||
const { isRememberEnabled, rememberDurationInDays, staticryptSaltUniqueVariableName } = staticryptConfig;
|
const { staticryptSaltUniqueVariableName } = staticryptConfig;
|
||||||
const { rememberExpirationKey, rememberPassphraseKey } = templateConfig;
|
|
||||||
|
|
||||||
// decrypt and replace the whole page
|
// decrypt and replace the whole page
|
||||||
const hashedPassword = await cryptoEngine.hashPassword(password, staticryptSaltUniqueVariableName);
|
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);
|
const isDecryptionSuccessful = await decryptAndReplaceHtml(hashedPassword);
|
||||||
|
|
||||||
|
@ -96,7 +102,7 @@ function init(staticryptConfig, templateConfig) {
|
||||||
hashedPassword,
|
hashedPassword,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.handleDecryptionOfPage = handleDecryptionOfPage;
|
exports.handleDecryptionOfPageFromHash = handleDecryptionOfPageFromHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear localstorage from staticrypt related values
|
* Clear localstorage from staticrypt related values
|
||||||
|
@ -193,21 +199,27 @@ function init(staticryptConfig, templateConfig) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptOnLoadFromUrl() {
|
async function decryptOnLoadFromUrl() {
|
||||||
const passwordKey = "staticrypt_pwd";
|
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 queryParams = new URLSearchParams(window.location.search);
|
||||||
const hashedPasswordQuery = queryParams.get(passwordKey);
|
const hashedPasswordQuery = queryParams.get(passwordKey);
|
||||||
|
const rememberMeQuery = queryParams.get(rememberMeKey);
|
||||||
|
|
||||||
|
const urlFragment = window.location.hash.substring(1);
|
||||||
// get the password from the url fragment
|
// get the password from the url fragment
|
||||||
const hashRegexMatch = window.location.hash.substring(1).match(new RegExp(passwordKey + "=(.*)"));
|
const hashedPasswordRegexMatch = urlFragment.match(new RegExp(passwordKey + "=([^&]*)"));
|
||||||
const hashedPasswordFragment = hashRegexMatch ? hashRegexMatch[1] : null;
|
const hashedPasswordFragment = hashedPasswordRegexMatch ? hashedPasswordRegexMatch[1] : null;
|
||||||
|
const rememberMeFragment = urlFragment.includes(rememberMeKey);
|
||||||
|
|
||||||
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
|
const hashedPassword = hashedPasswordFragment || hashedPasswordQuery;
|
||||||
|
const rememberMe = rememberMeFragment || rememberMeQuery;
|
||||||
|
|
||||||
if (hashedPassword) {
|
if (hashedPassword) {
|
||||||
return decryptAndReplaceHtml(hashedPassword);
|
return handleDecryptionOfPageFromHash(hashedPassword, rememberMe);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "staticrypt",
|
"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).",
|
"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",
|
"main": "index.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
|
Ładowanie…
Reference in New Issue