Skip to content

Commit

Permalink
added footer info and upgraded bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
joshterrill committed Jul 21, 2022
1 parent fad6589 commit 547bd7b
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 93 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hushnote",
"private": true,
"version": "4.0.0-rc.1",
"version": "4.0.0",
"description": "a privnote-like service with a REST API for sending one-time-use messages via unique URLs",
"main": "index.js",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions src/public/github.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 68 additions & 66 deletions src/views/home.handlebars
Original file line number Diff line number Diff line change
@@ -1,78 +1,80 @@
<textarea aria-label="Type message here" placeholder="Type message here" class="form-control" id="note" rows="14"></textarea> <br />
<div>
<input type="radio" name="message-type" value="onread" checked onchange="change(event)" aria-checked="true" aria-label="Destroy message after being read" /> Destroy message after being read <br />
<input id="ttl" type="radio" name="message-type" value="aftertime" onchange="change(event)" /> Destroy message after <input class="time-input" id="ttl-number" type="number" style="width: 40px" min="0" disabled />
<select class="time-input" id="ttl-unit" disabled aria-label="Destroy message after minutes, hours, days">
<option value="null">Select One</option>
<option value="60">Minutes</option>
<option value="3600">Hours</option>
<option value="84600">Days</options>
</select>
<textarea aria-label="Type message here" placeholder="Type message here" class="form-control" id="note" rows="14"></textarea>
<div class="mt-2 mb-2">
<input type="radio" name="message-type" value="onread" checked onchange="change(event)" aria-checked="true" aria-label="Destroy message after being read" /> Destroy message after being read <br />
<input id="ttl" type="radio" name="message-type" value="aftertime" onchange="change(event)" /> Destroy message after
<input class="time-input" id="ttl-number" type="number" style="width: 40px" min="0" disabled />
<select class="time-input" id="ttl-unit" disabled aria-label="Destroy message after minutes, hours, days">
<option value="null">Select One</option>
<option value="60">Minutes</option>
<option value="3600">Hours</option>
<option value="84600">Days</options>
</select>
</div>
<button class="btn btn-primary form-control" onclick="submit()" aria-label="Submit">Submit</button>
<button class="btn btn-default form-control" style="margin-top:8px;" onclick="restart()" aria-label="Clear">Clear</button>
<button class="btn btn-secondary form-control" style="margin-top:8px;" onclick="restart()"
aria-label="Clear">Clear</button>

<div id="results" style="font-size: 40px;margin-top:10px;text-align:center;display:none;">
<div class="input-group">
<span class="input-group-addon">URL:</span>
<input type="text" class="form-control" id="url" aria-label="Generated link to share" />
<span onclick="copyUrl()" id="copy" class="input-group-addon" style="cursor:pointer;" aria-label="Copy shareable link">Copy</span>
</div>
<div class="input-group">
<span class="input-group-addon">URL:</span>
<input type="text" class="form-control" id="url" aria-label="Generated link to share" />
<span onclick="copyUrl()" id="copy" class="input-group-addon" style="cursor:pointer;" aria-label="Copy shareable link">Copy</span>
</div>
</div>


<script>
async function submit() {
if (document.getElementById('ttl').checked && (document.getElementById('ttl-unit').value === 'null' || document.getElementById('ttl-number').value === '')) {
alert('You must enter a time and unit');
return;
async function submit() {
if (document.getElementById('ttl').checked && (document.getElementById('ttl-unit').value === 'null' || document.getElementById('ttl-number').value === '')) {
alert('You must enter a time and unit');
return;
}
const note = document.getElementById('note').value;
let ttl = 0;
if (document.getElementById('ttl').checked) {
ttl = document.getElementById('ttl-number').value * document.getElementById('ttl-unit').value;
}
const { securityKey, iv } = window.hush.generateIVAndSecurityKey();
const encryptedNote = window.hush.encrypt(note, iv, securityKey);
console.log(encryptedNote);
const opts = { note: encryptedNote, ttl, securityKey };
const response = await fetch('/create', {
method: 'POST',
body: JSON.stringify(opts),
headers: new Headers({
'Content-Type': 'application/json'
})
});
const urlInput = document.getElementById('url');
urlInput.value = `${location.origin}/read/${securityKey}/${iv}`;
document.getElementById('results').style.display = 'block';
urlInput.focus();
document.getElementById('note').value = '';
}
const note = document.getElementById('note').value;
let ttl = 0;
if (document.getElementById('ttl').checked) {
ttl = document.getElementById('ttl-number').value * document.getElementById('ttl-unit').value;
function copyUrl() {
document.getElementById('url').select();
document.execCommand('copy');
document.getElementById('copy').innerText = 'Copied!';
setTimeout(() => document.getElementById('copy').innerText = 'Copy', 2000)
}
function restart() {
document.getElementById('note').value = '';
document.getElementById('url').value = '';
document.getElementById('results').style.display = 'none';
}
const { securityKey, iv } = window.hush.generateIVAndSecurityKey();
const encryptedNote = window.hush.encrypt(note, iv, securityKey);
console.log(encryptedNote);
const opts = { note: encryptedNote, ttl, securityKey};
const response = await fetch('/create', {
method: 'POST',
body: JSON.stringify(opts),
headers: new Headers({
'Content-Type': 'application/json'
})
});
const urlInput = document.getElementById('url');
urlInput.value = `${location.origin}/read/${securityKey}/${iv}`;
document.getElementById('results').style.display = 'block';
urlInput.focus();
document.getElementById('note').value = '';
}
function copyUrl() {
document.getElementById('url').select();
document.execCommand('copy');
document.getElementById('copy').innerText = 'Copied!';
setTimeout(() => document.getElementById('copy').innerText = 'Copy', 2000)
}
function restart() {
document.getElementById('note').value = '';
document.getElementById('url').value = '';
document.getElementById('results').style.display = 'none';
}
function change(event) {
if (event.target.value === 'aftertime') {
document.querySelectorAll('.time-input').forEach(input => input.disabled = false);
document.getElementById('ttl-unit').value = null;
} else {
document.querySelectorAll('.time-input').forEach(input => {
input.value = null;
input.disabled = true;
});
function change(event) {
if (event.target.value === 'aftertime') {
document.querySelectorAll('.time-input').forEach(input => input.disabled = false);
document.getElementById('ttl-unit').value = null;
} else {
document.querySelectorAll('.time-input').forEach(input => {
input.value = null;
input.disabled = true;
});
}
document.getElementById('results').style.display = 'none';
}
document.getElementById('results').style.display = 'none';
}
</script>
</script>
43 changes: 36 additions & 7 deletions src/views/layouts/main.handlebars
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!doctype html>
<html>
<head>
<head>
<title>Hushnote</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<style>
.note-text-container {
white-space: pre-wrap;
Expand All @@ -12,13 +12,42 @@
word-wrap: break-word;
word-break: normal !important;
}
footer {
position: fixed;
bottom: 0;
width: 100%;
}
footer .container div:last-child {
margin-left: auto;
}
small.tagline {
font-size: 0.575em;
vertical-align: middle;
}
</style>
<script src="/crypto.min.js"></script>
</head>
<body>
</head>

<body>
<div class="container">
<h1>Hushnote <small>- A secure, client-encrypted, one-time messaging app</small></h1>
{{{body}}}
<h1>Hushnote <small class="text-secondary tagline">- A secure, client-encrypted, one-time messaging app</small></h1>
{{{body}}}
</div>
</body>
<footer class="footer mt-auto py-3 bg-light d-flex flex-columns">
<div class="container d-flex">
<div class="justify-content-start">
<span class="text-muted text-left">No copyright <span id="year"></span></span>
</div>
<div class="justify-content-end">
<a href="https://github.com/joshterrill/hushnote" target="_new">
<img style="width: 26px;" src="/github.svg" />
</a>
</div>
</div>
</footer>

<script>
document.getElementById('year').innerText = new Date().getFullYear();
</script>
</body>
</html>
38 changes: 19 additions & 19 deletions src/views/read.handlebars
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{{#if note}}
<h2>Note: </h2>
<pre id="note" class="note-text-container"></pre>
<h2>Note: </h2>
<pre id="note" class="note-text-container"></pre>
{{else}}
<h2 id="error">{{error}}</h2>
<h2 id="error">{{error}}</h2>
{{/if}}
<a href="/">Go back home</a>

{{#if note}}
<script>
try {
const [securityKey, iv] = location.pathname.split('/read/')[1].split('/');
const decryptedText = window.hush.decrypt('{{note}}', iv, securityKey);
const noteContainer = document.getElementById('note')
note.innerText = decryptedText;
note.setAttribute('aria-label', decryptedText);
} catch (error) {
console.error(error);
const errorContainer = document.getElementById('error');
if (!error?.message) {
error.message = 'Unable to read note, note has been destroyed.'
}
errorContainer.innerText = error.message;
}
</script>
<script>
try {
const [securityKey, iv] = location.pathname.split('/read/')[1].split('/');
const decryptedText = window.hush.decrypt('{{note}}', iv, securityKey);
const noteContainer = document.getElementById('note')
note.innerText = decryptedText;
note.setAttribute('aria-label', decryptedText);
} catch (error) {
console.error(error);
const errorContainer = document.getElementById('error');
if (!error?.message) {
error.message = 'Unable to read note, note has been destroyed.'
}
errorContainer.innerText = error.message;
}
</script>
{{/if}}

0 comments on commit 547bd7b

Please sign in to comment.