From 8fb936ea094af6881cb1c64ee33d6429b65564bc Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Mon, 17 Jul 2023 15:28:58 -0400 Subject: [PATCH] refactor: restructure and split up code --- src/contentProviders/baseProvider.ts | 2 +- src/dns.ts | 2 +- src/main/background.ts | 17 +- src/main/bootloader.ts | 298 +-------------------------- src/main/bootloader/kernel.ts | 82 ++++++++ src/main/bootloader/storage.ts | 51 +++++ src/main/bootloader/util.ts | 53 +++++ src/main/bootloader/vars.ts | 41 ++++ src/{main => }/vars.ts | 0 src/webEngine.ts | 4 +- 10 files changed, 248 insertions(+), 302 deletions(-) create mode 100644 src/main/bootloader/kernel.ts create mode 100644 src/main/bootloader/storage.ts create mode 100644 src/main/bootloader/util.ts create mode 100644 src/main/bootloader/vars.ts rename src/{main => }/vars.ts (100%) diff --git a/src/contentProviders/baseProvider.ts b/src/contentProviders/baseProvider.ts index 8f58a3c..1417a30 100644 --- a/src/contentProviders/baseProvider.ts +++ b/src/contentProviders/baseProvider.ts @@ -8,7 +8,7 @@ import { import WebEngine from "../webEngine.js"; import { getTld, isDomain, isIp, normalizeDomain } from "../util.js"; import tldEnum from "@lumeweb/tld-enum"; -import { getAuthStatus } from "../main/vars.js"; +import { getAuthStatus } from "../vars.js"; import { scanRecords } from "../dns.js"; export default abstract class BaseProvider { diff --git a/src/dns.ts b/src/dns.ts index 3cde4db..c05ee53 100644 --- a/src/dns.ts +++ b/src/dns.ts @@ -5,7 +5,7 @@ import { ResolverOptions, } from "@lumeweb/libresolver"; import { bufToHex } from "@lumeweb/libweb"; -import { getDnsSetupDefer } from "./main/vars.js"; +import { getDnsSetupDefer } from "./vars.js"; import { dnsClient } from "./clients.js"; import { blake3 } from "@noble/hashes/blake3"; diff --git a/src/main/background.ts b/src/main/background.ts index aa71a09..93c3059 100644 --- a/src/main/background.ts +++ b/src/main/background.ts @@ -30,7 +30,7 @@ import { setOpenPort, setTimer, weAreBooted, -} from "./vars.js"; +} from "../vars.js"; import browser from "webextension-polyfill"; function logLargeObjects() { @@ -93,7 +93,7 @@ function handleKernelMessage(event: MessageEvent) { } if (event.data.method === "log") { - if (data.isErr === false) { + if (data.isErr !== null && !data.isErr) { console.log(data.message); } else { console.error(data.message); @@ -103,11 +103,11 @@ function handleKernelMessage(event: MessageEvent) { if (event.data.method === "kernelAuthStatus") { setAuthStatus(data); - if (getAuthStatusKnown() === false) { + if (!getAuthStatusKnown()) { getAuthStatusResolve()(); setAuthStatusKnown(true); console.log("bootloader is now initialized"); - if (getAuthStatus().loginComplete !== true) { + if (!getAuthStatus().loginComplete) { console.log("user is not logged in: waiting until login is confirmed"); } } @@ -222,3 +222,12 @@ async function boot() { weAreBooted(); } + +browser.runtime.onInstalled.addListener(() => { + browser.tabs.create({ + url: browser.runtime.getURL("onboarding.html"), + active: true, + }); +}); + +boot(); diff --git a/src/main/bootloader.ts b/src/main/bootloader.ts index 351e03f..3db95a1 100644 --- a/src/main/bootloader.ts +++ b/src/main/bootloader.ts @@ -1,50 +1,14 @@ -import { - addContextToErr, - bufToStr, - Err, - hexToBuf, - objAsString, -} from "@lumeweb/libweb"; +import { boot } from "./bootloader/kernel.js"; declare var browser: any; // tsc -const defaultKernelLink = "RAC1FocOb2bQw6uwjN0AX__MJ8F-h71F5kvIgQPTKo7fQA"; - document.title = "kernel.lume"; let header = document.createElement("h1"); header.textContent = "Something went wrong! You should not be visiting this page, this page should only be accessed via an invisible iframe."; document.body.appendChild(header); -function bootloaderWLog(isErr: boolean, ...inputs: any) { - // Build the message, each item gets its own line. We do this because items - // are often full objects. - let message = "[lumeweb-kernel-bootloader]"; - for (let i = 0; i < inputs.length; i++) { - message += "\n"; - message += objAsString(inputs[i]); - } - - // Create the log by sending it to the parent. - window.parent.postMessage( - { - method: "log", - data: { - isErr, - message, - }, - }, - "*", - ); -} -function log(...inputs: any) { - bootloaderWLog(false, ...inputs); -} -function logErr(...inputs: any) { - bootloaderWLog(true, ...inputs); -} - -var handleIncomingMessage = function (event: MessageEvent) { +function handleIncomingMessage(event: MessageEvent) { if (event.source === null) { return; } @@ -75,12 +39,6 @@ var handleIncomingMessage = function (event: MessageEvent) { ); return; } - - if (event.data.method === "requestOverride") { - handleSkynetKernelRequestOverride(event); - return; - } - (event.source as WindowProxy).postMessage( { nonce: event.data.nonce, @@ -91,256 +49,8 @@ var handleIncomingMessage = function (event: MessageEvent) { event.origin, ); return; -}; -window.addEventListener("message", (event: MessageEvent) => { - handleIncomingMessage(event); -}); - -let kernelFavicon: Uint8Array; -let blockForFavicon: Promise = new Promise((resolve) => { - try { - let faviconURL = browser.runtime.getURL("icon@2x.png"); - fetch(faviconURL).then((response) => { - response.arrayBuffer().then((faviconData) => { - kernelFavicon = new Uint8Array(faviconData); - resolve(); - }); - }); - } catch { - kernelFavicon = new Uint8Array(0); - resolve(); - } -}); -let kernelAuthPage: Uint8Array; -let blockForAuthPage: Promise = new Promise((resolve) => { - try { - let authURL = browser.runtime.getURL("auth.html"); - fetch(authURL).then((response) => { - response.arrayBuffer().then((authData) => { - kernelAuthPage = new Uint8Array(authData); - resolve(); - }); - }); - } catch (err: any) { - kernelAuthPage = new TextEncoder().encode( - addContextToErr(err, "unable to load the kernel auth page"), - ); - resolve(); - } -}); -function handleSkynetKernelRequestOverride(event: MessageEvent) { - if (event.source === null) { - return; - } - - if (!event.origin.startsWith("moz")) { - return; - } - if (event.data.data.method !== "GET") { - return; - } - - let respondOverride = function (headers: any, body: Uint8Array) { - (event.source as WindowProxy).postMessage( - { - nonce: event.data.nonce, - method: "response", - err: null, - data: { - override: true, - headers, - body, - }, - }, - event.origin, - ); - }; - - if (event.data.data.url === "http://kernel.lume/favicon.ico") { - blockForFavicon.then(() => { - let headers = [ - { - name: "content-type", - value: "image/png", - }, - ]; - respondOverride(headers, kernelFavicon); - }); - return; - } - - if (event.data.data.url === "http://kernel.lume/auth.html") { - blockForAuthPage.then(() => { - let headers = [ - { - name: "content-type", - value: "text/html; charset=utf8", - }, - ]; - respondOverride(headers, kernelAuthPage); - }); - return; - } - - (event.source as WindowProxy).postMessage( - { - nonce: event.data.nonce, - method: "response", - err: null, - data: { - override: false, - }, - }, - event.origin, - ); } -var handleStorage = function (event: StorageEvent) { - if (event.key !== null && event.key !== "key") { - return; - } - if (logoutComplete === true) { - window.location.reload(); - return; - } +window.addEventListener("message", handleIncomingMessage); - if (event.key === null && loginComplete === false) { - return; - } - - if (event.key === "key" && loginComplete === false) { - let userSeedString = window.localStorage.getItem("key"); - if (userSeedString === null) { - sendAuthUpdate(); - return; - } - let [decodedSeed, errHTB] = hexToBuf(userSeedString); - if (errHTB !== null) { - logErr(addContextToErr(errHTB, "seed could not be decoded from hex")); - sendAuthUpdate(); - return; - } - userSeed = decodedSeed; - - log("user is now logged in, attempting to load kernel"); - loginComplete = true; - loadKernel(); - sendAuthUpdate(); - return; - } - - logoutComplete = true; - sendAuthUpdate(); - log("attempting to do a page reload"); - window.location.reload(); -}; -window.addEventListener("storage", (event) => handleStorage(event)); - -function downloadKernel( - kernelSkylink: string, -): Promise<[kernelCode: string, err: Err]> { - return new Promise((resolve) => { - fetch(`https://web3portal.com/${kernelSkylink}`).then((result) => { - if (result.status === 404) { - resolve(["", result.status.toString()]); - return; - } - if (!result.ok) { - resolve(["", result.statusText]); - return; - } - result - .blob() - .then((blob) => { - return blob.arrayBuffer(); - }) - .then((data) => { - let [kernelCode, errBBTS] = bufToStr(data); - - if (errBBTS !== null) { - resolve([ - "", - addContextToErr(null, "unable to decode the default kernel"), - ]); - return; - } - - resolve([kernelCode, null]); - }); - }); - }); -} - -function downloadDefaultKernel(): Promise<[kernelCode: string, err: Err]> { - return downloadKernel(defaultKernelLink); -} - -async function loadKernel() { - let [kernelCode, err] = await downloadDefaultKernel(); - - if (err !== null) { - let extErr = addContextToErr(err, "unable to download kernel"); - kernelLoaded = extErr; - logErr(extErr); - sendAuthUpdate(); - return; - } - - try { - eval(kernelCode); - kernelLoaded = "success"; - sendAuthUpdate(); - log("kernel successfully loaded"); - return; - } catch (err: any) { - let extErr = addContextToErr(err, "unable to eval kernel"); - kernelLoaded = extErr; - logErr(extErr); - logErr(err.toString()); - console.error(extErr); - console.error(err); - sendAuthUpdate(); - return; - } -} - -let loginComplete = false; -let logoutComplete = false; -let kernelLoaded = "not yet"; -function sendAuthUpdate() { - window.parent.postMessage( - { - method: "kernelAuthStatus", - data: { - loginComplete: loginComplete, - kernelLoaded: kernelLoaded, - logoutComplete: logoutComplete, - }, - }, - "*", - ); -} -sendAuthUpdate(); - -var userSeed: Uint8Array; -function checkForLoadKernel() { - let userSeedString = window.localStorage.getItem("v1-key"); - if (userSeedString === null) { - sendAuthUpdate(); - return; - } - let [decodedSeed, errHTB] = hexToBuf(userSeedString); - if (errHTB !== null) { - logErr(addContextToErr(errHTB, "seed could not be decoded from hex")); - sendAuthUpdate(); - return; - } - userSeed = decodedSeed; - - log("user is already logged in, attempting to load kernel"); - loginComplete = true; - sendAuthUpdate(); - loadKernel(); -} - -checkForLoadKernel(); +boot(); diff --git a/src/main/bootloader/kernel.ts b/src/main/bootloader/kernel.ts new file mode 100644 index 0000000..7ac8e9c --- /dev/null +++ b/src/main/bootloader/kernel.ts @@ -0,0 +1,82 @@ +import { + addContextToErr, + bufToStr, + downloadObject, + Err, + getActivePortals, + hexToBuf, +} from "@lumeweb/libweb"; +import { sendAuthUpdate } from "./util.js"; +import { log, logErr } from "@lumeweb/libkernel/kernel"; +import { + defaultKernelLink, + setBootloaderPortals, + setKernelLoaded, + setLoginComplete, +} from "./vars.js"; + +export function boot() { + let userKeyString = window.localStorage.getItem("key"); + if (userKeyString === null) { + sendAuthUpdate(); + return; + } + let [decodedSeed, errHTB] = hexToBuf(userKeyString); + if (errHTB !== null) { + logErr(addContextToErr(errHTB, "seed could not be decoded from hex")); + sendAuthUpdate(); + return; + } + + log("user is already logged in, attempting to load kernel"); + setLoginComplete(true); + sendAuthUpdate(); + loadKernel(); +} + +export async function loadKernel() { + let [kernelCode, err] = await downloadDefaultKernel(); + + if (err !== null) { + let extErr = addContextToErr(err, "unable to download kernel"); + setKernelLoaded(extErr); + logErr(extErr); + sendAuthUpdate(); + return; + } + + setBootloaderPortals(getActivePortals()); + + try { + eval(kernelCode); + setKernelLoaded("success"); + sendAuthUpdate(); + log("kernel successfully loaded"); + return; + } catch (err: any) { + let extErr = addContextToErr(err, "unable to eval kernel"); + setKernelLoaded(extErr); + logErr(extErr); + logErr(err.toString()); + console.error(extErr); + console.error(err); + sendAuthUpdate(); + return; + } +} + +async function downloadKernel( + kernelCid: string, +): Promise<[kernelCode: string, err: Err]> { + const [code, err] = await downloadObject(kernelCid); + + if (err != null) { + return ["", err]; + } + + return [code, null]; +} + +function downloadDefaultKernel(): Promise<[kernelCode: string, err: Err]> { + return downloadKernel(defaultKernelLink); +} diff --git a/src/main/bootloader/storage.ts b/src/main/bootloader/storage.ts new file mode 100644 index 0000000..85be2a9 --- /dev/null +++ b/src/main/bootloader/storage.ts @@ -0,0 +1,51 @@ +import { addContextToErr, hexToBuf } from "@lumeweb/libweb"; +import { + getLoginComplete, + getLogoutComplete, + setLoginComplete, + setLogoutComplete, + setUserKey, +} from "./vars.js"; +import { log, logErr, reloadKernel, sendAuthUpdate } from "./util.js"; +import { loadKernel } from "./kernel.js"; + +function handleStorage(event: StorageEvent) { + if (event.key !== null && event.key !== "key") { + return; + } + if (getLogoutComplete()) { + reloadKernel(); + return; + } + + if (event.key === null && getLoginComplete()) { + return; + } + + if (event.key === "key" && !getLoginComplete()) { + let userKey = window.localStorage.getItem("key"); + if (userKey === null) { + sendAuthUpdate(); + return; + } + let [decodedKey, errHTB] = hexToBuf(userKey); + if (errHTB !== null) { + logErr(addContextToErr(errHTB, "seed could not be decoded from hex")); + sendAuthUpdate(); + return; + } + setUserKey(decodedKey); + + log("user is now logged in, attempting to load kernel"); + setLoginComplete(true); + loadKernel(); + sendAuthUpdate(); + return; + } + setLogoutComplete(true); + sendAuthUpdate(); + log("attempting to do a page reload"); + reloadKernel(); +} + +window.addEventListener("storage", (event) => handleStorage(event)); diff --git a/src/main/bootloader/util.ts b/src/main/bootloader/util.ts new file mode 100644 index 0000000..acacba6 --- /dev/null +++ b/src/main/bootloader/util.ts @@ -0,0 +1,53 @@ +import { + getKernelLoaded, + getLoginComplete, + getLogoutComplete, +} from "./vars.js"; +import { objAsString } from "@lumeweb/libweb"; + +export function sendAuthUpdate() { + window.parent.postMessage( + { + method: "kernelAuthStatus", + data: { + loginComplete: getLoginComplete(), + kernelLoaded: getKernelLoaded(), + logoutComplete: getLogoutComplete, + }, + }, + "*", + ); +} + +function bootloaderWLog(isErr: boolean, ...inputs: any) { + // Build the message, each item gets its own line. We do this because items + // are often full objects. + let message = "[lumeweb-kernel-bootloader]"; + for (let i = 0; i < inputs.length; i++) { + message += "\n"; + message += objAsString(inputs[i]); + } + + // Create the log by sending it to the parent. + window.parent.postMessage( + { + method: "log", + data: { + isErr, + message, + }, + }, + "*", + ); +} + +export function log(...inputs: any) { + bootloaderWLog(false, ...inputs); +} +export function logErr(...inputs: any) { + bootloaderWLog(true, ...inputs); +} + +export function reloadKernel() { + window.location.reload(); +} diff --git a/src/main/bootloader/vars.ts b/src/main/bootloader/vars.ts new file mode 100644 index 0000000..1f250c1 --- /dev/null +++ b/src/main/bootloader/vars.ts @@ -0,0 +1,41 @@ +import { Client } from "@lumeweb/libportal"; + +let loginComplete = false; +let logoutComplete = false; +let kernelLoaded = "not yet"; +let bootloaderPortals: Client[] = []; + +var userKey: Uint8Array; + +export const defaultKernelLink = + "RAC1FocOb2bQw6uwjN0AX__MJ8F-h71F5kvIgQPTKo7fQA"; + +export function setLoginComplete(status: boolean) { + loginComplete = status; +} +export function getLoginComplete() { + return loginComplete; +} +export function setLogoutComplete(status: boolean) { + logoutComplete = status; +} +export function getLogoutComplete() { + return loginComplete; +} +export function setKernelLoaded(status: string) { + kernelLoaded = status; +} + +export function getKernelLoaded() { + return kernelLoaded; +} +export function setUserKey(key: Uint8Array) { + userKey = key; +} +export function getUserKey() { + return userKey; +} + +export function setBootloaderPortals(portals: Client[]) { + bootloaderPortals = portals; +} diff --git a/src/main/vars.ts b/src/vars.ts similarity index 100% rename from src/main/vars.ts rename to src/vars.ts diff --git a/src/webEngine.ts b/src/webEngine.ts index f3693c4..9d44743 100644 --- a/src/webEngine.ts +++ b/src/webEngine.ts @@ -14,7 +14,7 @@ import { getTld, isDomain, isIp, normalizeDomain } from "./util.js"; import tldEnum from "@lumeweb/tld-enum"; import { scanRecords } from "./dns.js"; import { bufToHex } from "@lumeweb/libweb"; -import { getAuthStatus } from "./main/vars.js"; +import { getAuthStatus } from "./vars.js"; import { DNSResult } from "@lumeweb/libresolver"; import { blake3 } from "@noble/hashes/blake3"; @@ -283,7 +283,7 @@ export default class WebEngine { return; } - if (getAuthStatus().loginComplete !== true) { + if (!getAuthStatus().loginComplete) { resolveRequest(); return; }