Compare commits
69 Commits
Author | SHA1 | Date |
---|---|---|
semantic-release-bot | b757ef5d7c | |
Derrick Hammer | c071eb4eb7 | |
Derrick Hammer | ea2530a22e | |
semantic-release-bot | b116388896 | |
Derrick Hammer | 3fc08a1e84 | |
Derrick Hammer | 31cabc6c0a | |
Derrick Hammer | 4e0021ef23 | |
Derrick Hammer | 312f8ab43a | |
semantic-release-bot | e1dc79c0dd | |
Derrick Hammer | 9bfbc3a145 | |
Derrick Hammer | a3f12abb78 | |
Derrick Hammer | cd7ad86869 | |
Derrick Hammer | c5f7059161 | |
Derrick Hammer | 760cade655 | |
semantic-release-bot | 94fa4f59a6 | |
Derrick Hammer | e31b86fdf8 | |
Derrick Hammer | f00738e609 | |
semantic-release-bot | edc6d75033 | |
Derrick Hammer | f8ca0c7afe | |
Derrick Hammer | e1699bc2d0 | |
Derrick Hammer | 4410def18c | |
semantic-release-bot | 31a2008d29 | |
Derrick Hammer | 8e1bd1a200 | |
Derrick Hammer | f3614350a8 | |
semantic-release-bot | e694eb1ed3 | |
Derrick Hammer | 91762070e4 | |
Derrick Hammer | 1f3cb20bd4 | |
Derrick Hammer | 1329712573 | |
semantic-release-bot | dba5089a56 | |
Derrick Hammer | 341e5ef128 | |
Derrick Hammer | 167dbe5c34 | |
semantic-release-bot | 7f64b8331b | |
Derrick Hammer | 46125cd893 | |
Derrick Hammer | 6b7d407153 | |
semantic-release-bot | 58d7ca2b9c | |
Derrick Hammer | 30ebcada31 | |
Derrick Hammer | dc9e4f13e9 | |
Derrick Hammer | 46a71bdfee | |
semantic-release-bot | 268bd41579 | |
Derrick Hammer | a9e3003929 | |
Derrick Hammer | 0eac4ae819 | |
semantic-release-bot | d8cbace466 | |
Derrick Hammer | 849e1f6bac | |
Derrick Hammer | c34e112610 | |
semantic-release-bot | 31118808c0 | |
Derrick Hammer | c101e80e19 | |
Derrick Hammer | 16dcb1f147 | |
semantic-release-bot | a6198aa5f7 | |
Derrick Hammer | c429adccbd | |
Derrick Hammer | dab3d5e246 | |
Derrick Hammer | 1227845e7d | |
semantic-release-bot | a38f731d0c | |
Derrick Hammer | 5c477ffb50 | |
Derrick Hammer | e1f040f0b7 | |
Derrick Hammer | 91fb8546e9 | |
Derrick Hammer | b66f8bbdc6 | |
semantic-release-bot | cd9743c023 | |
Derrick Hammer | b6664478b6 | |
Derrick Hammer | bd483134cc | |
semantic-release-bot | a5bd7fd001 | |
Derrick Hammer | 6fa0d49ce1 | |
Derrick Hammer | 97e083fb21 | |
Derrick Hammer | b1f476b504 | |
Derrick Hammer | 8d9af2a4c3 | |
semantic-release-bot | 2b248e3fdd | |
Derrick Hammer | d7e1b53d86 | |
Derrick Hammer | 45b8eddc4b | |
Derrick Hammer | 6a482df40d | |
Derrick Hammer | 3e9e5eda97 |
|
@ -0,0 +1,13 @@
|
||||||
|
name: Build/Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- develop-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
uses: lumeweb/github-node-deploy-workflow/.github/workflows/main.yml@master
|
||||||
|
secrets: inherit
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"preset": [
|
||||||
|
"@lumeweb/presetter-kernel-module-preset"
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"official": true,
|
||||||
|
"vite": {
|
||||||
|
"build": {
|
||||||
|
"lib": {
|
||||||
|
"formats": {
|
||||||
|
"0": "umd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_ENV=production run-s clean build:typescript:* build:vite build:html",
|
||||||
|
"build:vite": "vite build && shx mv lib/*.cjs lib/bootloader.js",
|
||||||
|
"build:html": "shx cp src/index.html lib/index.html"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
# [0.1.0-develop.18](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.17...v0.1.0-develop.18) (2023-11-18)
|
||||||
|
|
||||||
|
# [0.1.0-develop.17](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.16...v0.1.0-develop.17) (2023-11-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* correct handling of error code ([312f8ab](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/312f8ab43a5f781817e9b899a938719699c197c8))
|
||||||
|
* need to call sendAuthUpdate ([31cabc6](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/31cabc6c0a00ebb4e9379c4d81d7e4990457f2d3))
|
||||||
|
* need to use try/catch not if ([4e0021e](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/4e0021ef23f47ebc53b065b6221190786ccb6573))
|
||||||
|
|
||||||
|
# [0.1.0-develop.16](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.15...v0.1.0-develop.16) (2023-11-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* call savePortalSessions before kernel load ([c5f7059](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/c5f7059161223dfd96a718109bfb3b396539767b))
|
||||||
|
* need to add indexeddb detection due to browser security ([cd7ad86](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/cd7ad86869655cc6dbbe9078c49a295efd435b22))
|
||||||
|
|
||||||
|
# [0.1.0-develop.15](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.14...v0.1.0-develop.15) (2023-10-11)
|
||||||
|
|
||||||
|
# [0.1.0-develop.14](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.13...v0.1.0-develop.14) (2023-09-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add check for new worker domains and ignore any origins from them ([4410def](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/4410def18c03af1dfbd7271ce6a234331dfa4615))
|
||||||
|
|
||||||
|
# [0.1.0-develop.13](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.12...v0.1.0-develop.13) (2023-09-16)
|
||||||
|
|
||||||
|
# [0.1.0-develop.12](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.11...v0.1.0-develop.12) (2023-09-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* prevent loadKernel from running twice ([1329712](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/132971257354b73cbc6f1185dfaebaa4c9f925d3))
|
||||||
|
* save portals after booting, but before executing the kernel ([1f3cb20](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/1f3cb20bd424ae07bff97e9c5d79186ad533a349))
|
||||||
|
|
||||||
|
# [0.1.0-develop.11](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.10...v0.1.0-develop.11) (2023-09-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* set method in response ([167dbe5](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/167dbe5c342277c1003c5c9538c52d4e70770170))
|
||||||
|
|
||||||
|
# [0.1.0-develop.10](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.9...v0.1.0-develop.10) (2023-09-09)
|
||||||
|
|
||||||
|
# [0.1.0-develop.9](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.8...v0.1.0-develop.9) (2023-09-08)
|
||||||
|
|
||||||
|
# [0.1.0-develop.8](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.7...v0.1.0-develop.8) (2023-09-04)
|
||||||
|
|
||||||
|
# [0.1.0-develop.7](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.6...v0.1.0-develop.7) (2023-09-04)
|
||||||
|
|
||||||
|
# [0.1.0-develop.6](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.5...v0.1.0-develop.6) (2023-09-03)
|
||||||
|
|
||||||
|
# [0.1.0-develop.5](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.4...v0.1.0-develop.5) (2023-09-02)
|
||||||
|
|
||||||
|
# [0.1.0-develop.4](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.3...v0.1.0-develop.4) (2023-08-10)
|
||||||
|
|
||||||
|
# [0.1.0-develop.3](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.2...v0.1.0-develop.3) (2023-08-10)
|
||||||
|
|
||||||
|
# [0.1.0-develop.2](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.1.0-develop.1...v0.1.0-develop.2) (2023-07-21)
|
||||||
|
|
||||||
|
# [0.1.0-develop.1](https://git.lumeweb.com/LumeWeb/hosted-kernel/compare/v0.0.1...v0.1.0-develop.1) (2023-07-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* initial version ([3e9e5ed](https://git.lumeweb.com/LumeWeb/hosted-kernel/commit/3e9e5eda97cfc05f88575d1240f56fbf8543984c))
|
3
LICENSE
3
LICENSE
|
@ -1,6 +1,7 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 LumeWeb
|
Copyright (c) 2023 Hammer Technologies LLC
|
||||||
|
Copyright (c) 2022 Skynet Labs
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "@lumeweb/hosted-kernel",
|
||||||
|
"version": "0.1.0-develop.18",
|
||||||
|
"type": "module",
|
||||||
|
"readme": "ERROR: No README data found!",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "gitea@git.lumeweb.com:LumeWeb/hosted-kernel.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"prepare": "presetter bootstrap",
|
||||||
|
"build": "run build",
|
||||||
|
"semantic-release": "semantic-release"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@lumeweb/presetter-kernel-module-preset": "^0.1.0-develop.43"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@lumeweb/libkernel": "^0.1.0-develop.67",
|
||||||
|
"@noble/ciphers": "^0.1.4",
|
||||||
|
"binconv": "^0.2.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html class="no-js" lang="">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" src="./bootloader.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { boot } from "./kernel.js";
|
||||||
|
import { handleIncomingMessage } from "./messages.js";
|
||||||
|
|
||||||
|
document.title = "Hosted Lume Kernel";
|
||||||
|
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);
|
||||||
|
|
||||||
|
window.addEventListener("message", handleIncomingMessage);
|
||||||
|
|
||||||
|
boot();
|
|
@ -0,0 +1,166 @@
|
||||||
|
import {
|
||||||
|
downloadSmallObject,
|
||||||
|
maybeInitDefaultPortals,
|
||||||
|
savePortals,
|
||||||
|
savePortalSessions,
|
||||||
|
setActivePortalMasterKey,
|
||||||
|
} from "@lumeweb/libweb";
|
||||||
|
import { log, logErr, sendAuthUpdate } from "./util.js";
|
||||||
|
import {
|
||||||
|
defaultKernelLink,
|
||||||
|
setKernelLoaded,
|
||||||
|
setLoginComplete,
|
||||||
|
} from "./vars.js";
|
||||||
|
import { getStoredUserKey } from "./storage.js";
|
||||||
|
import { readableStreamToBlob } from "binconv";
|
||||||
|
import { addContextToErr } from "@lumeweb/libkernel";
|
||||||
|
|
||||||
|
let kernelLoadAttempt = false;
|
||||||
|
|
||||||
|
function testIndexedDBSupport() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Check for IndexedDB support
|
||||||
|
if (!("indexedDB" in window)) {
|
||||||
|
reject(new Error("IndexedDB is not supported by this browser."));
|
||||||
|
} else {
|
||||||
|
// Attempt to open an IndexedDB database
|
||||||
|
const request = indexedDB.open("test_db", 1);
|
||||||
|
|
||||||
|
request.onerror = function (event) {
|
||||||
|
// Error occurred, reject the promise
|
||||||
|
|
||||||
|
reject(
|
||||||
|
// @ts-ignore
|
||||||
|
new Error("IndexedDB test error: " + event?.target?.error?.code),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onsuccess = function (event) {
|
||||||
|
// Success, resolve the promise
|
||||||
|
// @ts-ignore
|
||||||
|
event?.target?.result.close(); // Close the DB when done
|
||||||
|
resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onupgradeneeded = function (event: IDBVersionChangeEvent) {
|
||||||
|
// Database needs to be created or upgraded
|
||||||
|
// @ts-ignore
|
||||||
|
const db = event?.target?.result;
|
||||||
|
if (!db.objectStoreNames.contains("test_store")) {
|
||||||
|
// Create an object store
|
||||||
|
db.createObjectStore("test_store", { keyPath: "id" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function boot() {
|
||||||
|
let userKey;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await testIndexedDBSupport();
|
||||||
|
} catch {
|
||||||
|
setKernelLoaded("indexeddb_error");
|
||||||
|
sendAuthUpdate();
|
||||||
|
logErr("indexed db is not supported or is blocked");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
userKey = getStoredUserKey();
|
||||||
|
} catch (e) {
|
||||||
|
logErr(addContextToErr(e, "user key could not be fetched"));
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userKey) {
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("user is already logged in, attempting to load kernel");
|
||||||
|
setActivePortalMasterKey(userKey);
|
||||||
|
setLoginComplete(true);
|
||||||
|
sendAuthUpdate();
|
||||||
|
loadKernel();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadKernel() {
|
||||||
|
if (kernelLoadAttempt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelLoadAttempt = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
maybeInitDefaultPortals();
|
||||||
|
} catch (e) {
|
||||||
|
let err = addContextToErr(e, "unable to init portals");
|
||||||
|
setKernelLoaded(err);
|
||||||
|
logErr(err);
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let kernelCode;
|
||||||
|
try {
|
||||||
|
kernelCode = await downloadDefaultKernel();
|
||||||
|
} catch (e) {
|
||||||
|
let extErr = addContextToErr(e, "unable to download kernel");
|
||||||
|
setKernelLoaded(extErr);
|
||||||
|
logErr(extErr);
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
savePortals();
|
||||||
|
savePortalSessions();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await new Promise(async (resolve, reject) => {
|
||||||
|
const url = URL.createObjectURL(await readableStreamToBlob(kernelCode));
|
||||||
|
|
||||||
|
const el = document.createElement("script");
|
||||||
|
el.src = url;
|
||||||
|
el.onload = () => {
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
resolve(null);
|
||||||
|
};
|
||||||
|
el.onerror = (
|
||||||
|
event: Event | string,
|
||||||
|
source?: string,
|
||||||
|
lineno?: number,
|
||||||
|
colno?: number,
|
||||||
|
error?: Error,
|
||||||
|
) => {
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.head.appendChild(el);
|
||||||
|
});
|
||||||
|
|
||||||
|
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<ReadableStream> {
|
||||||
|
return await downloadSmallObject(kernelCid);
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadDefaultKernel(): Promise<ReadableStream> {
|
||||||
|
return downloadKernel(defaultKernelLink);
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
import exchangeCommunicationKeys from "./messages/exchangeCommunicationKeys.js";
|
||||||
|
import setLoginKey from "./messages/setLoginKey.js";
|
||||||
|
|
||||||
|
const kernelMessageHandlers = {
|
||||||
|
exchangeCommunicationKeys,
|
||||||
|
setLoginKey,
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function handleIncomingMessage(event: MessageEvent) {
|
||||||
|
if (event.source === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.source === window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.origin.endsWith(".module.kernel.lumeweb.com")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!("nonce" in event.data)) {
|
||||||
|
(event.source as WindowProxy).postMessage(
|
||||||
|
{
|
||||||
|
nonce: "N/A",
|
||||||
|
method: "response",
|
||||||
|
err: "message sent to kernel with no nonce",
|
||||||
|
},
|
||||||
|
event.origin,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!("method" in event.data)) {
|
||||||
|
(event.source as WindowProxy).postMessage(
|
||||||
|
{
|
||||||
|
nonce: event.data.nonce,
|
||||||
|
method: "response",
|
||||||
|
err: "message sent to kernel with no method",
|
||||||
|
},
|
||||||
|
event.origin,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.data.method in kernelMessageHandlers) {
|
||||||
|
let response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await kernelMessageHandlers[event.data.method](
|
||||||
|
event.data.data,
|
||||||
|
);
|
||||||
|
} catch (e: any) {
|
||||||
|
response = { err: (e as Error).message };
|
||||||
|
}
|
||||||
|
|
||||||
|
(event.source as WindowProxy).postMessage(
|
||||||
|
{
|
||||||
|
nonce: event.data.nonce,
|
||||||
|
data: response,
|
||||||
|
method: "response",
|
||||||
|
},
|
||||||
|
event.origin,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (["moduleCall", "response"].includes(event.data.method)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(event.source as WindowProxy).postMessage(
|
||||||
|
{
|
||||||
|
nonce: event.data.nonce,
|
||||||
|
method: "response",
|
||||||
|
err:
|
||||||
|
"unrecognized method (user may need to log in): " + event.data.method,
|
||||||
|
},
|
||||||
|
event.origin,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { bytesToHex, hexToBytes } from "@lumeweb/libweb";
|
||||||
|
import {
|
||||||
|
getCommunicationPubKey,
|
||||||
|
setFrontendCommunicationPubkey,
|
||||||
|
} from "../vars.js";
|
||||||
|
import { log } from "../util.js";
|
||||||
|
|
||||||
|
export default function (data: any) {
|
||||||
|
setFrontendCommunicationPubkey(hexToBytes(data));
|
||||||
|
|
||||||
|
return bytesToHex(getCommunicationPubKey());
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { secretbox } from "@noble/ciphers/salsa";
|
||||||
|
import { x25519 } from "@noble/curves/ed25519";
|
||||||
|
import {
|
||||||
|
getCommunicationKey,
|
||||||
|
getFrontendCommunicationPubkey,
|
||||||
|
setLoginComplete,
|
||||||
|
} from "../vars.js";
|
||||||
|
import { saveUserKey } from "../storage.js";
|
||||||
|
import { hexToBytes } from "@lumeweb/libweb";
|
||||||
|
|
||||||
|
export default function (data: any) {
|
||||||
|
const box = secretbox(
|
||||||
|
x25519.getSharedSecret(
|
||||||
|
getCommunicationKey(),
|
||||||
|
getFrontendCommunicationPubkey(),
|
||||||
|
),
|
||||||
|
hexToBytes(data.nonce),
|
||||||
|
);
|
||||||
|
const decryptedData = box.open(hexToBytes(data.data));
|
||||||
|
|
||||||
|
setLoginComplete(false);
|
||||||
|
|
||||||
|
saveUserKey(decryptedData);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
import {
|
||||||
|
bytesToHex,
|
||||||
|
hexToBytes,
|
||||||
|
setActivePortalMasterKey,
|
||||||
|
} from "@lumeweb/libweb";
|
||||||
|
import { addContextToErr } from "@lumeweb/libkernel";
|
||||||
|
import {
|
||||||
|
getLoginComplete,
|
||||||
|
getLogoutComplete,
|
||||||
|
setLoginComplete,
|
||||||
|
setLogoutComplete,
|
||||||
|
} 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;
|
||||||
|
|
||||||
|
try {
|
||||||
|
userKey = getStoredUserKey();
|
||||||
|
} catch (e) {
|
||||||
|
logErr(addContextToErr(e, "user key could not be fetched"));
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userKey === null) {
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("user is now logged in, attempting to load kernel");
|
||||||
|
setActivePortalMasterKey(userKey);
|
||||||
|
setLoginComplete(true);
|
||||||
|
loadKernel();
|
||||||
|
sendAuthUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLogoutComplete(true);
|
||||||
|
sendAuthUpdate();
|
||||||
|
log("attempting to do a page reload");
|
||||||
|
reloadKernel();
|
||||||
|
}
|
||||||
|
window.addEventListener("storage", handleStorage);
|
||||||
|
|
||||||
|
export function saveUserKey(key: Uint8Array) {
|
||||||
|
window.localStorage.setItem("key", bytesToHex(key));
|
||||||
|
const event = new StorageEvent("storage", {
|
||||||
|
key: "key",
|
||||||
|
});
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStoredUserKey() {
|
||||||
|
const key = window.localStorage.getItem("key");
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
return hexToBytes(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
import {
|
||||||
|
getKernelLoaded,
|
||||||
|
getLoginComplete,
|
||||||
|
getLogoutComplete,
|
||||||
|
} from "./vars.js";
|
||||||
|
import { objAsString } from "@lumeweb/libkernel";
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { x25519 } from "@noble/curves/ed25519";
|
||||||
|
|
||||||
|
export const defaultKernelLink =
|
||||||
|
"z2H6zWHeWkVFirZ8jCzaPgSXqN9AqQFzQiBC2i4cnKnhwYynrrmA";
|
||||||
|
|
||||||
|
const store = new Map<string, any>(
|
||||||
|
Object.entries({
|
||||||
|
loginComplete: false,
|
||||||
|
logoutComplete: false,
|
||||||
|
kernelLoaded: "not yet",
|
||||||
|
communicationKey: null,
|
||||||
|
frontendCommunicationPubKey: null,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export function setLoginComplete(status: boolean) {
|
||||||
|
store.set("loginComplete", status);
|
||||||
|
}
|
||||||
|
export function getLoginComplete(): boolean {
|
||||||
|
return store.get("loginComplete");
|
||||||
|
}
|
||||||
|
export function setLogoutComplete(status: boolean) {
|
||||||
|
store.set("logoutComplete", status);
|
||||||
|
}
|
||||||
|
export function getLogoutComplete(): boolean {
|
||||||
|
return store.get("logoutComplete");
|
||||||
|
}
|
||||||
|
export function setKernelLoaded(status: string) {
|
||||||
|
store.set("kernelLoaded", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getKernelLoaded(): string {
|
||||||
|
return store.get("kernelLoaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCommunicationKey(): Uint8Array {
|
||||||
|
if (!store.get("communicationKey")) {
|
||||||
|
store.set("communicationKey", x25519.utils.randomPrivateKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
return store.get("communicationKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCommunicationPubKey() {
|
||||||
|
return x25519.getPublicKey(getCommunicationKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFrontendCommunicationPubkey(): Uint8Array {
|
||||||
|
return store.get("frontendCommunicationPubKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setFrontendCommunicationPubkey(key: Uint8Array) {
|
||||||
|
store.set("frontendCommunicationPubKey", key);
|
||||||
|
}
|
Loading…
Reference in New Issue