@secrecy/lib 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/lib/base-client.js +91 -0
- package/dist/lib/cache.js +4 -0
- package/dist/lib/client/SecrecryCareClient.js +19 -0
- package/dist/lib/client/SecrecyAppClient.js +87 -0
- package/dist/lib/client/SecrecyCloudClient.js +475 -0
- package/dist/lib/client/SecrecyDbClient.js +10 -0
- package/dist/lib/client/SecrecyMailClient.js +283 -0
- package/dist/lib/client/SecrecyPayClient.js +34 -0
- package/dist/lib/client/SecrecyUserClient.js +27 -0
- package/dist/lib/client/SecrecyWalletClient.js +50 -0
- package/dist/lib/client/convert/file.js +29 -0
- package/dist/lib/client/convert/mail.js +42 -0
- package/dist/lib/client/convert/node.js +100 -0
- package/dist/lib/client/helpers.js +103 -0
- package/dist/lib/client/index.js +49 -0
- package/dist/lib/client/storage.js +7 -0
- package/dist/lib/client/types/app.js +1 -0
- package/dist/lib/client/types/file.js +1 -0
- package/dist/lib/client/types/index.js +15 -0
- package/dist/lib/client/types/mail.js +1 -0
- package/dist/lib/client/types/node.js +1 -0
- package/dist/lib/client/types/user.js +1 -0
- package/dist/lib/client.js +47 -0
- package/dist/lib/crypto/file.js +184 -0
- package/dist/lib/crypto/index.js +41 -0
- package/dist/lib/error/client.js +10 -0
- package/dist/lib/error/index.js +10 -0
- package/dist/lib/error/server.js +27 -0
- package/dist/lib/index.js +10 -0
- package/dist/lib/minify/index.js +23 -0
- package/dist/lib/minify/lz4.js +517 -0
- package/dist/lib/sodium.js +5 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils/array.js +25 -0
- package/dist/lib/utils/base64.js +2 -0
- package/dist/lib/utils/popup-tools.js +180 -0
- package/dist/lib/utils/promise.js +20 -0
- package/dist/lib/utils/store-buddy.js +60 -0
- package/dist/lib/utils/time.js +13 -0
- package/dist/lib/worker/md5.js +18 -0
- package/dist/lib/worker/sodium.js +95 -0
- package/dist/lib/worker/workerCodes.js +254 -0
- package/dist/types/base-client.d.ts +28 -0
- package/dist/types/cache.d.ts +11 -0
- package/dist/types/client/SecrecryCareClient.d.ts +9 -0
- package/dist/types/client/SecrecyAppClient.d.ts +20 -0
- package/dist/types/client/SecrecyCloudClient.d.ts +88 -0
- package/dist/types/client/SecrecyDbClient.d.ts +7 -0
- package/dist/types/client/SecrecyMailClient.d.ts +42 -0
- package/dist/types/client/SecrecyPayClient.d.ts +27 -0
- package/dist/types/client/SecrecyUserClient.d.ts +14 -0
- package/dist/{client → types/client}/SecrecyWalletClient.d.ts +9 -12
- package/dist/types/client/convert/file.d.ts +4 -0
- package/dist/types/client/convert/mail.d.ts +8 -0
- package/dist/types/client/convert/node.d.ts +7 -0
- package/dist/types/client/helpers.d.ts +26 -0
- package/dist/types/client/index.d.ts +29 -0
- package/dist/{client → types/client}/storage.d.ts +2 -2
- package/dist/types/client/types/app.d.ts +2 -0
- package/dist/types/client/types/file.d.ts +6 -0
- package/dist/types/client/types/index.d.ts +46 -0
- package/dist/types/client/types/mail.d.ts +87 -0
- package/dist/{client/types/Node.d.ts → types/client/types/node.d.ts} +20 -25
- package/dist/types/client/types/user.d.ts +3 -0
- package/dist/types/client.d.ts +12138 -0
- package/dist/{crypto → types/crypto}/file.d.ts +4 -4
- package/dist/{crypto → types/crypto}/index.d.ts +1 -4
- package/dist/types/error/client.d.ts +22 -0
- package/dist/types/error/index.d.ts +40 -0
- package/dist/types/error/server.d.ts +26 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/{minify → types/minify}/index.d.ts +1 -1
- package/dist/types/minify/lz4.d.ts +35 -0
- package/dist/{sodium.d.ts → types/sodium.d.ts} +1 -1
- package/dist/types/types.d.ts +10 -0
- package/dist/{utils/utils.d.ts → types/utils/array.d.ts} +0 -1
- package/dist/types/utils/base64.d.ts +1 -0
- package/dist/types/utils/popup-tools.d.ts +52 -0
- package/dist/types/utils/promise.d.ts +1 -0
- package/dist/types/utils/store-buddy.d.ts +130 -0
- package/dist/{worker → types/worker}/sodium.d.ts +1 -1
- package/package.json +48 -73
- package/dist/BaseClient.d.ts +0 -111
- package/dist/BaseClient.js +0 -506
- package/dist/PopupTools.d.ts +0 -17
- package/dist/PopupTools.js +0 -195
- package/dist/ZeusThunder.d.ts +0 -2
- package/dist/ZeusThunder.js +0 -65
- package/dist/cache.d.ts +0 -6
- package/dist/cache.js +0 -4
- package/dist/client/SecrecyAppClient.d.ts +0 -17
- package/dist/client/SecrecyAppClient.js +0 -226
- package/dist/client/SecrecyCloudClient.d.ts +0 -89
- package/dist/client/SecrecyCloudClient.js +0 -1405
- package/dist/client/SecrecyDbClient.d.ts +0 -48
- package/dist/client/SecrecyDbClient.js +0 -419
- package/dist/client/SecrecyMailClient.d.ts +0 -42
- package/dist/client/SecrecyMailClient.js +0 -1022
- package/dist/client/SecrecyPayClient.d.ts +0 -28
- package/dist/client/SecrecyPayClient.js +0 -68
- package/dist/client/SecrecyWalletClient.js +0 -73
- package/dist/client/convert/file.d.ts +0 -5
- package/dist/client/convert/file.js +0 -33
- package/dist/client/convert/mail.d.ts +0 -3
- package/dist/client/convert/mail.js +0 -42
- package/dist/client/convert/node.d.ts +0 -9
- package/dist/client/convert/node.js +0 -87
- package/dist/client/helpers.d.ts +0 -28
- package/dist/client/helpers.js +0 -119
- package/dist/client/index.d.ts +0 -34
- package/dist/client/index.js +0 -46
- package/dist/client/storage.js +0 -12
- package/dist/client/types/File.d.ts +0 -14
- package/dist/client/types/File.js +0 -3
- package/dist/client/types/Inputs.d.ts +0 -16
- package/dist/client/types/Inputs.js +0 -3
- package/dist/client/types/Node.js +0 -3
- package/dist/client/types/UserAppNotifications.d.ts +0 -6
- package/dist/client/types/UserAppNotifications.js +0 -3
- package/dist/client/types/UserAppSettings.d.ts +0 -5
- package/dist/client/types/UserAppSettings.js +0 -3
- package/dist/client/types/index.d.ts +0 -120
- package/dist/client/types/index.js +0 -8
- package/dist/client/types/selectors.d.ts +0 -400
- package/dist/client/types/selectors.js +0 -135
- package/dist/crypto/file.js +0 -195
- package/dist/crypto/index.js +0 -45
- package/dist/error.d.ts +0 -33
- package/dist/error.js +0 -3
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -10
- package/dist/minify/index.js +0 -23
- package/dist/minify/lz4.d.ts +0 -5
- package/dist/minify/lz4.js +0 -539
- package/dist/sodium.js +0 -6
- package/dist/utils/encoders.d.ts +0 -26
- package/dist/utils/encoders.js +0 -18
- package/dist/utils/store-buddy.d.ts +0 -14
- package/dist/utils/store-buddy.js +0 -58
- package/dist/utils/time.js +0 -12
- package/dist/utils/utils.js +0 -47
- package/dist/worker/md5.js +0 -24
- package/dist/worker/sodium.js +0 -118
- package/dist/worker/workerCodes.js +0 -255
- package/dist/zeus/const.d.ts +0 -7
- package/dist/zeus/const.js +0 -1846
- package/dist/zeus/index.d.ts +0 -8721
- package/dist/zeus/index.js +0 -642
- /package/dist/{utils → types/utils}/time.d.ts +0 -0
- /package/dist/{worker → types/worker}/md5.d.ts +0 -0
- /package/dist/{worker → types/worker}/workerCodes.d.ts +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BaseClient } from '../base-client.js';
|
|
2
|
+
import { encryptSecretstream } from '../crypto/file.js';
|
|
3
|
+
import { sodium } from '../sodium.js';
|
|
4
|
+
import { SecrecyCloudClient } from './SecrecyCloudClient.js';
|
|
5
|
+
import { SecrecyMailClient } from './SecrecyMailClient.js';
|
|
6
|
+
import { SecrecyAppClient } from './SecrecyAppClient.js';
|
|
7
|
+
import { nodesCache, filesCache, publicKeysCache } from '../cache.js';
|
|
8
|
+
import { SecrecyDbClient } from './SecrecyDbClient.js';
|
|
9
|
+
import { SecrecyWalletClient } from './SecrecyWalletClient.js';
|
|
10
|
+
import { SecrecyPayClient } from './SecrecyPayClient.js';
|
|
11
|
+
import { SecrecyUserClient } from './SecrecyUserClient.js';
|
|
12
|
+
import { SecrecyCareClient } from './SecrecryCareClient.js';
|
|
13
|
+
export const encryptName = async (name, nameKey) => {
|
|
14
|
+
const { data } = await encryptSecretstream(sodium.from_hex(nameKey), sodium.from_string(name));
|
|
15
|
+
const nameEncrypted = sodium.to_hex(data);
|
|
16
|
+
return nameEncrypted;
|
|
17
|
+
};
|
|
18
|
+
export class SecrecyClient extends BaseClient {
|
|
19
|
+
#keys;
|
|
20
|
+
care;
|
|
21
|
+
cloud;
|
|
22
|
+
mail;
|
|
23
|
+
app;
|
|
24
|
+
db;
|
|
25
|
+
wallet;
|
|
26
|
+
pay;
|
|
27
|
+
user;
|
|
28
|
+
constructor(uaSession, uaKeys, uaJwt) {
|
|
29
|
+
super(uaSession);
|
|
30
|
+
this.#keys = uaKeys;
|
|
31
|
+
this.care = new SecrecyCareClient(this, this.#keys, this.client);
|
|
32
|
+
this.cloud = new SecrecyCloudClient(this, this.#keys, this.client);
|
|
33
|
+
this.mail = new SecrecyMailClient(this, this.#keys, this.client);
|
|
34
|
+
this.app = new SecrecyAppClient(uaJwt, this, this.#keys, this.client);
|
|
35
|
+
this.db = new SecrecyDbClient(this, this.#keys, this.client);
|
|
36
|
+
this.wallet = new SecrecyWalletClient(this);
|
|
37
|
+
this.pay = new SecrecyPayClient(this, this.#keys, this.client);
|
|
38
|
+
this.user = new SecrecyUserClient(this, this.#keys, this.client);
|
|
39
|
+
}
|
|
40
|
+
get publicKey() {
|
|
41
|
+
return this.#keys.publicKey;
|
|
42
|
+
}
|
|
43
|
+
async logout(sessionId) {
|
|
44
|
+
nodesCache.clear();
|
|
45
|
+
filesCache.clear();
|
|
46
|
+
publicKeysCache.clear();
|
|
47
|
+
await super.logout(sessionId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { storeBuddy } from '../utils/store-buddy.js';
|
|
2
|
+
export function getStorage(session) {
|
|
3
|
+
const userAppSession = storeBuddy(`secrecy.user_app_session`, session).init(null);
|
|
4
|
+
const userAppKeys = storeBuddy(`secrecy.user_app_keys`, session).init(null);
|
|
5
|
+
const jwt = storeBuddy(`secrecy.jwt`, session).init(null);
|
|
6
|
+
return { userAppKeys, userAppSession, jwt };
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const keyPair = z
|
|
3
|
+
.object({
|
|
4
|
+
publicKey: z.string(),
|
|
5
|
+
privateKey: z.string(),
|
|
6
|
+
})
|
|
7
|
+
.strict();
|
|
8
|
+
export const secrecyUserApp = z
|
|
9
|
+
.object({
|
|
10
|
+
keys: keyPair,
|
|
11
|
+
jwt: z.string(),
|
|
12
|
+
uaSession: z.string(),
|
|
13
|
+
})
|
|
14
|
+
.strict()
|
|
15
|
+
.readonly();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { httpBatchLink, loggerLink, createTRPCProxyClient, TRPCClientError, } from '@trpc/client';
|
|
2
|
+
import superjson from 'superjson';
|
|
3
|
+
export function isTRPCClientError(cause) {
|
|
4
|
+
return cause instanceof TRPCClientError;
|
|
5
|
+
}
|
|
6
|
+
export const createTRPCClient = (session, onAccessDenied) => createTRPCProxyClient({
|
|
7
|
+
transformer: superjson,
|
|
8
|
+
links: [
|
|
9
|
+
loggerLink({
|
|
10
|
+
enabled: (op) => {
|
|
11
|
+
if (op.direction === 'down' &&
|
|
12
|
+
isTRPCClientError(op.result) &&
|
|
13
|
+
op.result.data?.code === 'UNAUTHORIZED') {
|
|
14
|
+
onAccessDenied?.();
|
|
15
|
+
}
|
|
16
|
+
return (process.env.NODE_ENV === 'development' ||
|
|
17
|
+
(op.direction === 'down' && op.result instanceof Error));
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
httpBatchLink({
|
|
21
|
+
url: process.env.NEXT_PUBLIC_SECRECY_API_URL ??
|
|
22
|
+
'https://api.secrecy.tech/',
|
|
23
|
+
maxURLLength: 2083,
|
|
24
|
+
fetch: async (input, init) => {
|
|
25
|
+
const controller = new AbortController();
|
|
26
|
+
const id = setTimeout(() => {
|
|
27
|
+
controller.abort();
|
|
28
|
+
}, 20000);
|
|
29
|
+
const headers = new Headers(init?.headers);
|
|
30
|
+
if (typeof session === 'string') {
|
|
31
|
+
headers.set('secrecy-session', session);
|
|
32
|
+
}
|
|
33
|
+
const call = fetch(input, {
|
|
34
|
+
...init,
|
|
35
|
+
headers,
|
|
36
|
+
signal: controller.signal,
|
|
37
|
+
mode: 'cors',
|
|
38
|
+
credentials: 'same-origin',
|
|
39
|
+
});
|
|
40
|
+
void call.finally(() => {
|
|
41
|
+
clearTimeout(id);
|
|
42
|
+
});
|
|
43
|
+
return await call;
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
});
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { setup, sodium } from '../sodium.js';
|
|
2
|
+
import SparkMD5 from 'spark-md5';
|
|
3
|
+
import { chunks } from '../utils/array.js';
|
|
4
|
+
function assert(c, message) {
|
|
5
|
+
if (!c) {
|
|
6
|
+
throw new Error(message);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function secretstreamKeygen() {
|
|
10
|
+
return sodium.crypto_secretstream_xchacha20poly1305_keygen();
|
|
11
|
+
}
|
|
12
|
+
function encrypt(key) {
|
|
13
|
+
let destroyed = false;
|
|
14
|
+
const { state, header } = sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
|
|
15
|
+
const encrypt = (tag, plaintext) => {
|
|
16
|
+
assert(!destroyed, 'state already destroyed');
|
|
17
|
+
return sodium.crypto_secretstream_xchacha20poly1305_push(state, plaintext, null, tag);
|
|
18
|
+
};
|
|
19
|
+
function destroy() {
|
|
20
|
+
assert(!destroyed, 'state already destroyed');
|
|
21
|
+
destroyed = true;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
encrypt,
|
|
25
|
+
destroy,
|
|
26
|
+
header,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function decrypt(header, key) {
|
|
30
|
+
assert(header.byteLength >=
|
|
31
|
+
sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES, `header must be at least HEADERBYTES (${sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES}) long`);
|
|
32
|
+
assert(key.byteLength >= sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES, `key must be at least KEYBYTES (${sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES}) long`);
|
|
33
|
+
let destroyed = false;
|
|
34
|
+
const state = sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, key);
|
|
35
|
+
const decrypt = (ciphertext) => {
|
|
36
|
+
assert(!destroyed, 'state already destroyed');
|
|
37
|
+
return sodium.crypto_secretstream_xchacha20poly1305_pull(state, ciphertext);
|
|
38
|
+
};
|
|
39
|
+
function destroy() {
|
|
40
|
+
assert(!destroyed, 'state already destroyed');
|
|
41
|
+
destroyed = true;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
decrypt,
|
|
45
|
+
destroy,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export const CHUNK_SIZE = 8192;
|
|
49
|
+
export async function encryptSecretstream(key, data, progress, abort) {
|
|
50
|
+
await setup();
|
|
51
|
+
const { encrypt: crypt, destroy, header } = encrypt(key);
|
|
52
|
+
const encryptedChunk = CHUNK_SIZE + sodium.crypto_secretstream_xchacha20poly1305_ABYTES;
|
|
53
|
+
const max = Math.ceil(data.byteLength / CHUNK_SIZE) * encryptedChunk + header.byteLength;
|
|
54
|
+
void progress?.({
|
|
55
|
+
percent: 0,
|
|
56
|
+
total: max,
|
|
57
|
+
current: 0,
|
|
58
|
+
});
|
|
59
|
+
const final = new Uint8Array(max);
|
|
60
|
+
const sparkEncrypted = new SparkMD5.ArrayBuffer();
|
|
61
|
+
const spark = new SparkMD5.ArrayBuffer();
|
|
62
|
+
final.set(header);
|
|
63
|
+
sparkEncrypted.append(header.buffer);
|
|
64
|
+
let total = header.byteLength;
|
|
65
|
+
void progress?.({
|
|
66
|
+
percent: total / max,
|
|
67
|
+
total: max,
|
|
68
|
+
current: total,
|
|
69
|
+
});
|
|
70
|
+
let lastPercent = total / max;
|
|
71
|
+
for (const chunk of chunks(data, CHUNK_SIZE)) {
|
|
72
|
+
if (abort?.signal.aborted === true) {
|
|
73
|
+
throw new Error(`Encrypt aborted`);
|
|
74
|
+
}
|
|
75
|
+
spark.append(chunk.buffer);
|
|
76
|
+
const tag = chunk.length < CHUNK_SIZE
|
|
77
|
+
? sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
|
|
78
|
+
: sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE;
|
|
79
|
+
const encrypted = crypt(tag, chunk);
|
|
80
|
+
sparkEncrypted.append(encrypted.buffer);
|
|
81
|
+
final.set(encrypted, total);
|
|
82
|
+
total += encrypted.byteLength;
|
|
83
|
+
const percent = total / max;
|
|
84
|
+
if (percent > lastPercent + 0.01) {
|
|
85
|
+
void progress?.({
|
|
86
|
+
percent,
|
|
87
|
+
total: max,
|
|
88
|
+
current: total,
|
|
89
|
+
});
|
|
90
|
+
lastPercent = percent;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
destroy();
|
|
94
|
+
void progress?.({
|
|
95
|
+
percent: 1,
|
|
96
|
+
total,
|
|
97
|
+
current: total,
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
data: final.slice(0, total),
|
|
101
|
+
md5Encrypted: sparkEncrypted.end(),
|
|
102
|
+
md5: spark.end(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export async function decryptSecretstream(key, data, progress, abort) {
|
|
106
|
+
await setup();
|
|
107
|
+
const header = data.slice(0, sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES);
|
|
108
|
+
data = data.slice(sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES);
|
|
109
|
+
const { decrypt: decryptt, destroy } = decrypt(header, key);
|
|
110
|
+
const chunkSize = CHUNK_SIZE + sodium.crypto_secretstream_xchacha20poly1305_ABYTES;
|
|
111
|
+
const max = Math.ceil(data.byteLength / chunkSize) * CHUNK_SIZE;
|
|
112
|
+
void progress?.({
|
|
113
|
+
percent: 0,
|
|
114
|
+
total: max,
|
|
115
|
+
current: 0,
|
|
116
|
+
});
|
|
117
|
+
const final = new Uint8Array(max);
|
|
118
|
+
let total = 0;
|
|
119
|
+
let lastPercent = total / max;
|
|
120
|
+
for (const chunk of chunks(data, chunkSize)) {
|
|
121
|
+
if (abort?.signal.aborted === true) {
|
|
122
|
+
throw new Error(`Decrypt aborted`);
|
|
123
|
+
}
|
|
124
|
+
const tmp = decryptt(chunk);
|
|
125
|
+
final.set(tmp.message, total);
|
|
126
|
+
total += tmp.message.byteLength;
|
|
127
|
+
const percent = total / max;
|
|
128
|
+
if (percent > lastPercent + 0.01) {
|
|
129
|
+
void progress?.({
|
|
130
|
+
percent,
|
|
131
|
+
total: max,
|
|
132
|
+
current: total,
|
|
133
|
+
});
|
|
134
|
+
lastPercent = percent;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
destroy();
|
|
138
|
+
void progress?.({
|
|
139
|
+
percent: 1,
|
|
140
|
+
total,
|
|
141
|
+
current: total,
|
|
142
|
+
});
|
|
143
|
+
return final.slice(0, total);
|
|
144
|
+
}
|
|
145
|
+
// async function mainSecretstream(random: Uint8Array): Promise<vo id> {
|
|
146
|
+
// const key = secretstreamKeygen();
|
|
147
|
+
// console.time("secretstream_encrypt");
|
|
148
|
+
// const crypted = en cryptSecretstream(key, random);
|
|
149
|
+
// consol e.timeEnd("secretstream_encrypt");
|
|
150
|
+
// console.time("secretstream_decrypt");
|
|
151
|
+
// const decrypted = decryptSecretstream(key, crypted);
|
|
152
|
+
// con sole.timeEnd("secretstream_decrypt");
|
|
153
|
+
// const first = t o_hex(random).slice(0, 32);
|
|
154
|
+
// const final = to_hex(decrypted).slice(0, 32);
|
|
155
|
+
// console.lo g({
|
|
156
|
+
// first,
|
|
157
|
+
// final,
|
|
158
|
+
// equals: firs t === final
|
|
159
|
+
// }) ;
|
|
160
|
+
// }
|
|
161
|
+
// async function mai nSecretbox(random: Uint8Array): Promise< void> {
|
|
162
|
+
// const key = generateSecretBox();
|
|
163
|
+
// console.time("secretbox _encrypt");
|
|
164
|
+
// const crypted = encryptFile(random, key);
|
|
165
|
+
// console.timeEn d("secretbox_encrypt");
|
|
166
|
+
// console.time("secretbox_decrypt");
|
|
167
|
+
// const decrypted = decryptFile(crypted, key);
|
|
168
|
+
// console.tim eEnd("secretbox_decrypt");
|
|
169
|
+
// const first = to_h ex(random).slice(0, 32);
|
|
170
|
+
// const final = to_hex(decrypted).slice(0, 32);
|
|
171
|
+
// console.lo g({
|
|
172
|
+
// first,
|
|
173
|
+
// final,
|
|
174
|
+
// equals: firs t === final
|
|
175
|
+
// }) ;
|
|
176
|
+
// }
|
|
177
|
+
// asy nc function ma in(): Promise<void> {
|
|
178
|
+
// await ready;
|
|
179
|
+
// console.time("randombytes_buf");
|
|
180
|
+
// const random = randombytes_buf(1_000_000 * 1024);
|
|
181
|
+
// consol e.timeEnd("randombytes_buf");
|
|
182
|
+
// await Promise.all([m ainSecretstream(random), mainSecretbox(random)]);
|
|
183
|
+
// }
|
|
184
|
+
// main();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { concatenate } from '../utils/array.js';
|
|
2
|
+
import { sodium } from '../sodium.js';
|
|
3
|
+
export function encryptCryptoBox(data, publicKeyBob, privateKeyAlice) {
|
|
4
|
+
const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
|
|
5
|
+
const crypt = sodium.crypto_box_easy(data, nonce, sodium.from_hex(publicKeyBob), sodium.from_hex(privateKeyAlice));
|
|
6
|
+
return concatenate(nonce, crypt);
|
|
7
|
+
}
|
|
8
|
+
export function generateCryptoBoxKeyPair() {
|
|
9
|
+
return sodium.crypto_box_keypair('hex');
|
|
10
|
+
}
|
|
11
|
+
export function decryptCryptoBox(data, publicKeyAlice, privateKeyBob) {
|
|
12
|
+
if (data.length < sodium.crypto_box_NONCEBYTES + sodium.crypto_box_MACBYTES) {
|
|
13
|
+
throw 'data too short';
|
|
14
|
+
}
|
|
15
|
+
const nonce = data.slice(0, sodium.crypto_box_NONCEBYTES);
|
|
16
|
+
const cipher = data.slice(sodium.crypto_box_NONCEBYTES);
|
|
17
|
+
return sodium.crypto_box_open_easy(cipher, nonce, sodium.from_hex(publicKeyAlice), sodium.from_hex(privateKeyBob));
|
|
18
|
+
}
|
|
19
|
+
export function generateSecretBoxKey() {
|
|
20
|
+
return sodium.randombytes_buf(sodium.crypto_secretbox_KEYBYTES, 'hex');
|
|
21
|
+
}
|
|
22
|
+
export function encryptSecretBox(data, key) {
|
|
23
|
+
const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
|
|
24
|
+
const crypt = sodium.crypto_secretbox_easy(data, nonce, sodium.from_hex(key));
|
|
25
|
+
return concatenate(nonce, crypt);
|
|
26
|
+
}
|
|
27
|
+
export function decryptSecretBox(data, key) {
|
|
28
|
+
if (data.length <
|
|
29
|
+
sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES) {
|
|
30
|
+
throw 'data too short';
|
|
31
|
+
}
|
|
32
|
+
const nonce = data.slice(0, sodium.crypto_secretbox_NONCEBYTES);
|
|
33
|
+
const cipher = data.slice(sodium.crypto_secretbox_NONCEBYTES);
|
|
34
|
+
return sodium.crypto_secretbox_open_easy(cipher, nonce, sodium.from_hex(key));
|
|
35
|
+
}
|
|
36
|
+
export function encryptAnonymous(data, receiverPublicKey) {
|
|
37
|
+
return sodium.crypto_box_seal(data, sodium.from_hex(receiverPublicKey));
|
|
38
|
+
}
|
|
39
|
+
export function decryptAnonymous(data, { privateKey, publicKey }) {
|
|
40
|
+
return sodium.crypto_box_seal_open(data, sodium.from_hex(publicKey), sodium.from_hex(privateKey));
|
|
41
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const clientErrorCodeKey = z.enum(['NOT_FOUND']);
|
|
3
|
+
export const clientError = z.object({
|
|
4
|
+
name: z.literal('ClientError'),
|
|
5
|
+
code: clientErrorCodeKey,
|
|
6
|
+
message: z.string(),
|
|
7
|
+
});
|
|
8
|
+
export const isClientError = (input) => {
|
|
9
|
+
return clientError.safeParse(input).success;
|
|
10
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { clientError } from './client.js';
|
|
3
|
+
import { serverError } from './server.js';
|
|
4
|
+
export const secrecyError = z.discriminatedUnion('name', [
|
|
5
|
+
serverError,
|
|
6
|
+
clientError,
|
|
7
|
+
]);
|
|
8
|
+
export const isSecrecyError = (input) => {
|
|
9
|
+
return secrecyError.safeParse(input).success;
|
|
10
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const trpcErrorCodeKey = z.enum([
|
|
3
|
+
'PARSE_ERROR',
|
|
4
|
+
'BAD_REQUEST',
|
|
5
|
+
'INTERNAL_SERVER_ERROR',
|
|
6
|
+
'NOT_IMPLEMENTED',
|
|
7
|
+
'UNAUTHORIZED',
|
|
8
|
+
'FORBIDDEN',
|
|
9
|
+
'NOT_FOUND',
|
|
10
|
+
'METHOD_NOT_SUPPORTED',
|
|
11
|
+
'TIMEOUT',
|
|
12
|
+
'CONFLICT',
|
|
13
|
+
'PRECONDITION_FAILED',
|
|
14
|
+
'PAYLOAD_TOO_LARGE',
|
|
15
|
+
'UNPROCESSABLE_CONTENT',
|
|
16
|
+
'TOO_MANY_REQUESTS',
|
|
17
|
+
'CLIENT_CLOSED_REQUEST',
|
|
18
|
+
]);
|
|
19
|
+
export const serverError = z.object({
|
|
20
|
+
name: z.literal('TRPCError'),
|
|
21
|
+
code: trpcErrorCodeKey,
|
|
22
|
+
message: z.string(),
|
|
23
|
+
data: z.unknown().optional(),
|
|
24
|
+
});
|
|
25
|
+
export const isServerError = (input) => {
|
|
26
|
+
return serverError.safeParse(input).success;
|
|
27
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/triple-slash-reference */
|
|
2
|
+
/// <reference lib="dom" />
|
|
3
|
+
/// <reference lib="dom.iterable" />
|
|
4
|
+
export * from './client/index.js';
|
|
5
|
+
export * from './crypto/index.js';
|
|
6
|
+
export { BaseClient } from './base-client.js';
|
|
7
|
+
export * from './client/helpers.js';
|
|
8
|
+
export * from './sodium.js';
|
|
9
|
+
export * from './utils/store-buddy.js';
|
|
10
|
+
export * from './error/index.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { calcUncompressedLen, compressBlockBound, compressBlockHC, uncompressBlock, } from './lz4.js';
|
|
2
|
+
import { concatenate } from '../utils/array.js';
|
|
3
|
+
export function compress(data) {
|
|
4
|
+
// If the data is too small, it's not worth compressing.
|
|
5
|
+
if (data.byteLength < 15_000_000) {
|
|
6
|
+
return concatenate(new Uint8Array([0]), data);
|
|
7
|
+
}
|
|
8
|
+
const compressed = new Uint8Array(compressBlockBound(data.byteLength));
|
|
9
|
+
const compressedSize = compressBlockHC(data, compressed, 0);
|
|
10
|
+
if (compressedSize === 0) {
|
|
11
|
+
return concatenate(new Uint8Array([0]), data);
|
|
12
|
+
}
|
|
13
|
+
return concatenate(new Uint8Array([1]), compressed.slice(0, compressedSize));
|
|
14
|
+
}
|
|
15
|
+
export function decompress(data) {
|
|
16
|
+
const realData = data.slice(1);
|
|
17
|
+
if (data[0] === 0) {
|
|
18
|
+
return realData;
|
|
19
|
+
}
|
|
20
|
+
const dst = new Uint8Array(calcUncompressedLen(realData));
|
|
21
|
+
const uncompressedSize = uncompressBlock(realData, dst);
|
|
22
|
+
return dst.slice(0, uncompressedSize);
|
|
23
|
+
}
|