From b2968962e7acd5bcb1659d8e51d7487b40b834fe Mon Sep 17 00:00:00 2001 From: Neil Movva Date: Wed, 15 Feb 2023 00:53:54 -0800 Subject: [PATCH] Private Valentines demo (#9) JS Client changes: Gracefully return null if key is not found in bucket (instead of throwing) Support single and multi-key lookups in a unified privateRead function --- .gitignore | 2 + .../fonts/IBMPlexMono-Regular.woff2 | Bin 0 -> 39328 bytes examples/valentines/package.json | 36 ++ examples/valentines/public/index.html | 19 + examples/valentines/sandbox.config.json | 5 + examples/valentines/src/App.tsx | 432 ++++++++++++++++++ examples/valentines/src/index.tsx | 13 + examples/valentines/src/styles.css | 218 +++++++++ examples/valentines/src/util.tsx | 28 ++ examples/valentines/tsconfig.json | 26 ++ js/bucket/bucket.ts | 41 +- js/bucket/bucket_service.ts | 5 +- package.json | 2 +- 13 files changed, 819 insertions(+), 8 deletions(-) create mode 100644 examples/valentines/fonts/IBMPlexMono-Regular.woff2 create mode 100644 examples/valentines/package.json create mode 100644 examples/valentines/public/index.html create mode 100644 examples/valentines/sandbox.config.json create mode 100644 examples/valentines/src/App.tsx create mode 100644 examples/valentines/src/index.tsx create mode 100644 examples/valentines/src/styles.css create mode 100644 examples/valentines/src/util.tsx create mode 100644 examples/valentines/tsconfig.json diff --git a/.gitignore b/.gitignore index 599e44c..0f29cce 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ node_modules .env/ *.pyc +*build/ +.DS_Store diff --git a/examples/valentines/fonts/IBMPlexMono-Regular.woff2 b/examples/valentines/fonts/IBMPlexMono-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..84c87e05a773f1ee2155f09dfc646b0b6d72f197 GIT binary patch literal 39328 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 ki;BIT#n}y6bpA@xCP{M z0ESqUCXz1cG8o_+^vv9EDMQnFn;@E}Wbu6D;0X|E9-V7zLvsm8+DI1d zq3e6X5Z=2A7A<$@SCLxm>12}Y5Vb&r+3wyhImap9`Rt{~wfBR$1QeJE9R)if)$qWq zd!QBn-%wBAqBBXB`|iNSopl!PYM)6oQM&&|NgL#ShlODz?d*^DL*@dtDh4Go1#m~2 zb64{qD&(XbeZ}W`eimjv-lGIkdG=@PE=2FXjMS&t0Gd|k3Qb)q+QDd`B7oW<)#V7(Qa5TUnvT;Yl#!YGenXuRk zQU{5EoOGq)$+&+moovm7$wZEVs9dTxa9K+er8baju41NA8kCfD`HXZiA%KGWBR+yO zKpHu`cNoCv)3(gt-^i+nX+v59uTQhm^wYEwb6%sOC~dT;a#adZ(5cqKOmzMM=bWOZ zG>7BJ08JRs^F?!W?tK~P+WkWO<3RK&0umR1 WuS*)Ls$3 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⁢F}>!G!)c5q%khWy1rf%!Gg< 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 + + + + + + Private Valentine Retrieval + + + + +
+ + diff --git a/examples/valentines/sandbox.config.json b/examples/valentines/sandbox.config.json new file mode 100644 index 0000000..2019957 --- /dev/null +++ b/examples/valentines/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "infiniteLoopProtection": false, + "hardReloadOnChange": false, + "view": "browser" +} diff --git a/examples/valentines/src/App.tsx b/examples/valentines/src/App.tsx new file mode 100644 index 0000000..22b5afe --- /dev/null +++ b/examples/valentines/src/App.tsx @@ -0,0 +1,432 @@ +import './styles.css'; +import { Log, LogMessage } from './util'; +import { Bucket, Client } from '@blyss/sdk'; +import React, { useState } from 'react'; + +// This function gets called only on the first query +async function setup(apiKey: string): Promise { + const client = new Client(apiKey); + + // Create the bucket, if it doesn't exist. + // By default, only you can read and write from the buckets you create. + // To make a bucket others can read, prefix the name with "global." + const bucketName = 'global.private-valentines-13643'; + if (!(await client.exists(bucketName))) { + console.log('creating bucket'); + await client.create(bucketName); + } + + // Connect to your bucket + const bucket = await client.connect(bucketName); + + return bucket; +} + +async function deriveMessageKey(recipient: string): Promise { + // 0.1. Create base key material from recipient handle + const baseKey = await window.crypto.subtle.importKey( + 'raw', + new TextEncoder().encode(recipient), + { name: 'PBKDF2' }, + false, + ['deriveKey'] + ); + + const pkbdf2Params = { + name: 'PBKDF2', + salt: new TextEncoder().encode('valentine'), + iterations: 100000, + hash: 'SHA-256' + }; + + const aesGenKeyParams = { + name: 'AES-GCM', + length: 256 + }; + + const key = await window.crypto.subtle.deriveKey( + pkbdf2Params, + baseKey, + aesGenKeyParams, + false, + ['encrypt', 'decrypt'] + ); + + return key; +} + +async function computeServerKey(mailbox: string): Promise { + // 2.2. Hash recipient's handle to get destination key on server + const hash = await window.crypto.subtle.digest( + 'SHA-256', + new TextEncoder().encode(mailbox) + ); + // 2.3. Convert hash to base64 string + const targetKey = window.btoa(String.fromCharCode(...new Uint8Array(hash))); + return targetKey; +} + +function SendValentineCard({ + loading, + handler +}: { + loading: boolean; + handler: (e: React.FormEvent) => void; +}) { + return ( +
+

😘 Send

+
+

To:

+ +
+
+

Valentine message:

+