feat: change the application to use url hash for the encryption key (#167)

* feat: change the application to use url hash for the encryption key

the application will still support use url params for a while, but will be removed at the 4.0 breaking release

* chore: update the hemmelig.ts file with the output

* chore: bump the version
This commit is contained in:
bjarneo 2023-03-22 07:30:11 +01:00 committed by GitHub
parent f82f3aa1da
commit 4323c6bb6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 70 deletions

8
cli.js
View File

@ -29,15 +29,15 @@ const cli = meow(
Examples
$ hemmelig "my super secret" --password=1337
[*] Hemmelig.app URL: https://hemmelig.app/secret/myencryptionkey/thesecretid
[*] Hemmelig.app URL: https://hemmelig.app/secret/thesecretid#encryption_key=myencryptionkey
# Pipe data to the hemmelig cli
$ cat mysecret.txt | hemmelig
[*] Hemmelig.app URL: https://hemmelig.app/secret/myencryptionkey2/thesecretid2
[*] Hemmelig.app URL: https://hemmelig.app/secret/thesecretid2#encryption_key=myencryptionkey2
# Different output
$ hemmelig "I am secret" -o=json
{"encryptionKey":"9LiWq3iMAF0IkQs1tecOxbYKFesEnTN9","secretId":"manageable_CEsgWtxEaNNbwld6PjwyF1bQaiy4jQl9","url":"https://hemmelig.app/secret/9LiWq3iMAF0IkQs1tecOxbYKFesEnTN9/manageable_CEsgWtxEaNNbwld6PjwyF1bQaiy4jQl9"}
{"encryptionKey":"9LiWq3iMAF0IkQs1tecOxbYKFesEnTN9","secretId":"manageable_CEsgWtxEaNNbwld6PjwyF1bQaiy4jQl9","url":"https://hemmelig.app/secret/manageable_CEsgWtxEaNNbwld6PjwyF1bQaiy4jQl9#encryption_key=9LiWq3iMAF0IkQs1tecOxbYKFesEnTN9"}
`,
{
importMeta: { url },
@ -109,7 +109,7 @@ const createSecret = async (data = {}) => {
};
const getSecretURL = (encryptionKey, secretId) =>
`${cli.flags.url}/secret/${encryptionKey}/${secretId}`;
`${cli.flags.url}/secret/${secretId}#encryption_key=${encryptionKey}`;
const createOutput = (encryptionKey, secretId) => {
const url = getSecretURL(encryptionKey, secretId);

View File

@ -1,82 +1,90 @@
const completionSpec: Fig.Spec = {
"name": "hemmelig",
"description": "Encrypt text",
"args": [
name: 'hemmelig',
description: 'Encrypt text',
args: [
{
"name": "text",
"description": "Text"
}
name: 'text',
description: 'Text',
},
],
"options": [
options: [
{
"name": ["-t", "--title"],
"description": "The secret title",
"isOptional": true,
"args": {
"name": "title",
"description": "The secret title"
}
name: ['-t', '--title'],
description: 'The secret title',
isOptional: true,
args: {
name: 'title',
description: 'The secret title',
},
},
{
"name": ["-p", "--password"],
"description": "The password to protect the secret",
"isOptional": true,
"args": {
"name": "password",
"description": "The password to protect the secret"
}
name: ['-p', '--password'],
description: 'The password to protect the secret',
isOptional: true,
args: {
name: 'password',
description: 'The password to protect the secret',
},
},
{
"name": ["-l", "--lifetime"],
"description": "The lifetime of the secret",
"isOptional": true,
"args": {
"name": "lifetime",
"description": "The lifetime of the secret"
}
name: ['-l', '--lifetime'],
description: 'The lifetime of the secret',
isOptional: true,
args: {
name: 'lifetime',
description: 'The lifetime of the secret',
},
},
{
"name": ["-m", "--maxViews"],
"description": "The max views of the secret",
"isOptional": true,
"args": {
"name": "maxViews",
"description": "The max views of the secret"
}
name: ['-m', '--maxViews'],
description: 'The max views of the secret',
isOptional: true,
args: {
name: 'maxViews',
description: 'The max views of the secret',
},
},
{
"name": ["-c", "--cidr"],
"description": "Provide the IP or CIDR range",
"isOptional": true,
"args": {
"name": "cidr",
"description": "Provide the IP or CIDR range"
}
name: ['-c', '--cidr'],
description: 'Provide the IP or CIDR range',
isOptional: true,
args: {
name: 'cidr',
description: 'Provide the IP or CIDR range',
},
},
{
"name": ["-e", "--expire"],
"description": "Burn the secret only after the expire time",
"isOptional": true,
"args": {
"name": "expire",
"description": "Burn the secret only after the expire time"
}
name: ['-e', '--expire'],
description: 'Burn the secret only after the expire time',
isOptional: true,
args: {
name: 'expire',
description: 'Burn the secret only after the expire time',
},
},
{
"name": ["-u", "--url"],
"description": "If you have your own instance of the Hemmelig.app",
"isOptional": true,
"args": {
"name": "url",
"description": "If you have your own instance of the Hemmelig.app"
}
name: ['-u', '--url'],
description: 'If you have your own instance of the Hemmelig.app',
isOptional: true,
args: {
name: 'url',
description: 'If you have your own instance of the Hemmelig.app',
},
},
{
"name": "--help",
"description": "Prints help information",
"isOptional": true,
}
]
name: ['-o', '--output'],
description: 'Do you want the output response in yaml or json',
isOptional: true,
args: {
name: 'output',
description: 'Do you want the output response in yaml or json',
},
},
{
name: '--help',
description: 'Prints help information',
isOptional: true,
},
],
};
export default completionSpec;

View File

@ -1,6 +1,6 @@
{
"name": "hemmelig",
"version": "4.3.0",
"version": "4.4.0",
"description": "Paste a password, secret message or private information",
"main": "index.js",
"type": "module",

View File

@ -159,6 +159,9 @@ const App = () => {
<Route path="/secret/:encryptionKey/:secretId" exact>
<Secret />
</Route>
<Route path="/secret/:secretId" exact>
<Secret />
</Route>
<Route path="/signin" exact>
<SignIn />
</Route>

View File

@ -198,7 +198,8 @@ const Home = () => {
const handleFocus = (event) => event.target.select();
const getSecretURL = () => `${window.location.origin}/secret/${encryptionKey}/${secretId}`;
const getSecretURL = () =>
`${window.location.origin}/secret/${secretId}#encryption_key=${encryptionKey}`;
const inputReadOnly = !!secretId;

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { useParams, Link } from 'react-router-dom';
import { useParams, Link, useLocation } from 'react-router-dom';
import { Button, Group, Container, Textarea, TextInput, Stack, Title, Text } from '@mantine/core';
import {
@ -19,10 +19,24 @@ import { decrypt } from '../../../shared/helpers/crypto';
import { useTranslation } from 'react-i18next';
const getEncryptionKeyHash = (hash) => {
const id = '#encryption_key=';
if (!hash || !hash.includes(id)) {
return '';
}
const [_, encryptionKey] = hash.split('#encryption_key=');
return encryptionKey;
};
const Secret = () => {
const { t } = useTranslation();
const { secretId, encryptionKey = null } = useParams();
const { hash = '' } = useLocation();
const { secretId, encryptionKey = getEncryptionKeyHash(hash) } = useParams();
const [secret, setSecret] = useState(null);
const [title, setTitle] = useState(null);
const [preventBurn, setPreventBurn] = useState(false);