Skip to content

Commit

Permalink
Merge pull request #53 from fullstackedorg/p2p
Browse files Browse the repository at this point in the history
Peer-to-Peer Connectivity
  • Loading branch information
cplepage authored Jun 13, 2024
2 parents cc970d9 + 24fe506 commit 727b82b
Show file tree
Hide file tree
Showing 81 changed files with 4,474 additions and 1,479 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "editor-sample-demo"]
path = editor-sample-demo
url = https://github.com/fullstackedorg/editor-sample-demo.git
[submodule "lib/go"]
path = lib/go
url = https://github.com/golang/go.git
2 changes: 1 addition & 1 deletion editor-sample-demo
18 changes: 9 additions & 9 deletions editor/api/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import rpc from "../../rpc";

import git from "../git";
import projects from "../projects";

import { Project, GitAuths } from "../projects/types";
import { Project, GitAuths, Connectivity } from "../projects/types";
import { CONFIG_TYPE } from "./types";

type DATA_TYPE = {
[CONFIG_TYPE.PROJECTS]: Project[];
[CONFIG_TYPE.GIT]: GitAuths;
[CONFIG_TYPE.CONNECTIVITY]: Connectivity;
};

export default {
Expand All @@ -17,17 +17,17 @@ export default {
if (await rpc().fs.exists(configDir, { absolutePath: true })) return;

await rpc().fs.mkdir(configDir, { absolutePath: true });
await projects.import(
const project = await projects.import(
{
title: "Demo",
location: "fullstackedorg/editor-sample-demo"
// TODO: uncomment when webcontainer git CORS fixed
// gitRepository: {
// url: "https://github.com/fullstackedorg/editor-sample-demo.git"
// }
location: "fullstackedorg/editor-sample-demo",
gitRepository: {
url: "https://github.com/fullstackedorg/editor-sample-demo.git"
}
},
(await rpc().fs.readFile("Demo.zip")) as Uint8Array
);
await git.init(project);
},
async load<T extends CONFIG_TYPE>(type: T): Promise<DATA_TYPE[T] | null> {
const configDir = await rpc().directories.config();
Expand Down
3 changes: 2 additions & 1 deletion editor/api/config/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum CONFIG_TYPE {
PROJECTS = "projects",
GIT = "git"
GIT = "git",
CONNECTIVITY = "connectivity"
}
82 changes: 82 additions & 0 deletions editor/api/connectivity/cryptoUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// for large strings, use this from https://stackoverflow.com/a/49124600
export const toBase64 = (data: ArrayBufferLike) =>
btoa(
new Uint8Array(data).reduce(
(data, byte) => data + String.fromCharCode(byte),
""
)
);

export const fromBase64 = (data: string) =>
Uint8Array.from(atob(data), (c) => c.charCodeAt(null));

export const generateHash = (byteLength: number) =>
toBase64(crypto.getRandomValues(new Uint8Array(byteLength)));

const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();

export async function encrypt(data: string, key: string) {
const salt = crypto.getRandomValues(new Uint8Array(16));
const iv = crypto.getRandomValues(new Uint8Array(12));
const cryptoKey = await importKey(key);
const derivedKey = await deriveKey(cryptoKey, salt, "encrypt");
const encryptedContent = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv
},
derivedKey,
textEncoder.encode(data)
);

const encryptedContentArr = new Uint8Array(encryptedContent);
let buff = new Uint8Array(
salt.byteLength + iv.byteLength + encryptedContentArr.byteLength
);
buff.set(salt, 0);
buff.set(iv, salt.byteLength);
buff.set(encryptedContentArr, salt.byteLength + iv.byteLength);
return toBase64(buff);
}

export async function decrypt(base64: string, key: string) {
const encryptedDataBuff = fromBase64(base64);
const salt = encryptedDataBuff.slice(0, 16);
const iv = encryptedDataBuff.slice(16, 16 + 12);
const data = encryptedDataBuff.slice(16 + 12);
const cryptoKey = await importKey(key);
const derivedKey = await deriveKey(cryptoKey, salt, "decrypt");
const decryptedContent = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv
},
derivedKey,
data
);
return textDecoder.decode(decryptedContent);
}

const importKey = (key: string) =>
crypto.subtle.importKey("raw", textEncoder.encode(key), "PBKDF2", false, [
"deriveKey"
]);

const deriveKey = (
cryptoKey: CryptoKey,
salt: ArrayBufferLike,
keyUsage: "encrypt" | "decrypt"
) =>
crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 250000,
hash: "SHA-256"
},
cryptoKey,
{ name: "AES-GCM", length: 256 },
false,
[keyUsage]
);
Loading

0 comments on commit 727b82b

Please sign in to comment.