-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
88 lines (69 loc) · 2.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const assert = require('assert');
const superagent = require('superagent');
const randomstring = require('randomstring').generate;
const GibberishAES = require('gibberish-aes/src/gibberish-aes');
const PRIVNOTE_BASE_URL = 'https://privnote.com';
const PRIVNOTE_BASE_HEADERS = { 'X-Requested-With': 'XMLHttpRequest' };
const PRIVNOTE_AUTO_PASSPHRASE_LENGTH = 9;
const PRIVNOTE_CIPHER = 'aes-256-cbc';
exports.createPrivnote = async (
body,
{ passphrase = null, ask = true, durationHours = 0 } = {}
) => {
const hasManualPassphrase = passphrase !== null;
if (!hasManualPassphrase) {
passphrase = randomstring({
length: PRIVNOTE_AUTO_PASSPHRASE_LENGTH,
charset: 'alphanumeric',
});
}
// const passphraseBuffer = Buffer.from(passphrase);
const ciphertextBase64 = GibberishAES.enc(
body.toString(),
passphrase.toString()
);
const response = await superagent
.post(`${PRIVNOTE_BASE_URL}/legacy/`)
.type('form')
.set(PRIVNOTE_BASE_HEADERS)
.send({
'': '',
data: ciphertextBase64,
has_manual_pass: hasManualPassphrase.toString(),
duration_hours: durationHours,
dont_ask: (!ask).toString(),
data_type: 'T',
notify_email: '',
notify_ref: '',
});
const noteId = response.body.note_link.match(/[^/]+$/)[0];
return {
id: noteId,
url: `${PRIVNOTE_BASE_URL}/${noteId}#${passphrase}`,
passphrase,
};
};
exports.retrievePrivnote = async (idOrUrl, passphrase) => {
assert(idOrUrl, 'idOrUrl is required');
const match = idOrUrl.match(`^${PRIVNOTE_BASE_URL}\\/([^#]+)#(.+)$`);
let id;
if (match) {
id = match[1];
passphrase = match[2];
} else {
id = idOrUrl;
}
assert(passphrase, 'passphrase is required');
const response = await superagent
.delete(`${PRIVNOTE_BASE_URL}/${id}`)
.set(PRIVNOTE_BASE_HEADERS);
const { destroyed, data: ciphertext } = response.body;
if (!ciphertext) {
throw new Error(`Note was destroyed on ${destroyed}`);
}
const cleartext = GibberishAES.dec(ciphertext, passphrase.toString());
return cleartext;
};
exports.isPrivnoteUrl = url =>
typeof url === 'string' &&
!!url.match(/^https:\/\/privnote.com\/[a-zA-Z0-9]+#[a-zA-Z0-9]+$/);