*Update builds
This commit is contained in:
parent
6d15e76560
commit
baf1fa7695
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
export {};
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
// @ts-ignore
|
||||||
|
const index_js_1 = require("../dist/index.js");
|
||||||
|
const puppeteer_1 = require("puppeteer");
|
||||||
|
let browser;
|
||||||
|
(async () => {
|
||||||
|
browser = await puppeteer_1.default.launch({ headless: false, devtools: true });
|
||||||
|
const page = (await browser.pages()).pop();
|
||||||
|
await (0, index_js_1.login)(page);
|
||||||
|
await (0, index_js_1.loadTester)(page);
|
||||||
|
})();
|
||||||
|
process.on("SIGTERM", async () => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
|
@ -2,7 +2,7 @@ import { Page } from "puppeteer";
|
||||||
import { errTuple } from "libskynet/dist";
|
import { errTuple } from "libskynet/dist";
|
||||||
export declare const KERNEL_TEST_SUITE = "AQCPJ9WRzMpKQHIsPo8no3XJpUydcDCjw7VJy8lG1MCZ3g";
|
export declare const KERNEL_TEST_SUITE = "AQCPJ9WRzMpKQHIsPo8no3XJpUydcDCjw7VJy8lG1MCZ3g";
|
||||||
export declare const KERNEL_HELPER_MODULE = "AQCoaLP6JexdZshDDZRQaIwN3B7DqFjlY7byMikR7u1IEA";
|
export declare const KERNEL_HELPER_MODULE = "AQCoaLP6JexdZshDDZRQaIwN3B7DqFjlY7byMikR7u1IEA";
|
||||||
export declare const TEST_KERNEL_SKLINK = "AQCw2_9rg0Fxuy8ky3pvLiDhcJTmAqthy1Buc7Frl2v2fA";
|
export declare const TEST_KERNEL_SKLINK = "AQDJDoXMJiiEMBxXodQvUV89qtQHsnXWyV1ViQ9M1pMjUg";
|
||||||
export declare function generateSeedPhrase(): string;
|
export declare function generateSeedPhrase(): string;
|
||||||
export declare function login(page: Page, seed?: string): Promise<void>;
|
export declare function login(page: Page, seed?: string): Promise<void>;
|
||||||
export declare function loadTester(page: Page, port?: number): Promise<void>;
|
export declare function loadTester(page: Page, port?: number): Promise<void>;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
214
public/tester.js
214
public/tester.js
|
@ -37,108 +37,109 @@
|
||||||
console.error("[libkernel]", ...inputs);
|
console.error("[libkernel]", ...inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryStringify will try to turn the provided input into a string. If the input
|
// objAsString will try to return the provided object as a string. If the
|
||||||
// object is already a string, the input object will be returned. If the input
|
// object is already a string, it will be returned without modification. If the
|
||||||
// object has a toString method, the toString method will be called. If that
|
// object is an 'Error', the message of the error will be returned. If the object
|
||||||
// fails, we try to call JSON.stringify on the object. And if that fails, we
|
// has a toString method, the toString method will be called and the result
|
||||||
// set the return value to "[stringify failed]".
|
// will be returned. If the object is null or undefined, a special string will
|
||||||
function tryStringify$1(obj) {
|
// be returned indicating that the undefined/null object cannot be converted to
|
||||||
|
// a string. In all other cases, JSON.stringify is used. If JSON.stringify
|
||||||
|
// throws an exception, a message "[could not provide object as string]" will
|
||||||
|
// be returned.
|
||||||
|
//
|
||||||
|
// NOTE: objAsString is intended to produce human readable output. It is lossy,
|
||||||
|
// and it is not intended to be used for serialization.
|
||||||
|
function objAsString(obj) {
|
||||||
// Check for undefined input.
|
// Check for undefined input.
|
||||||
if (obj === undefined || obj === null) {
|
if (obj === undefined) {
|
||||||
return "[cannot stringify undefined input]";
|
return "[cannot convert undefined to string]";
|
||||||
|
}
|
||||||
|
if (obj === null) {
|
||||||
|
return "[cannot convert null to string]";
|
||||||
}
|
}
|
||||||
// Parse the error into a string.
|
// Parse the error into a string.
|
||||||
if (typeof obj === "string") {
|
if (typeof obj === "string") {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
// Check if the object has a custom toString and use that if so.
|
// Check if the object is an error, and return the message of the error if
|
||||||
let hasToString = typeof obj.toString === "function";
|
// so.
|
||||||
if (hasToString && obj.toString !== Object.prototype.toString) {
|
if (obj instanceof Error) {
|
||||||
return obj.toString();
|
return obj.message;
|
||||||
|
}
|
||||||
|
// Check if the object has a 'toString' method defined on it. To ensure
|
||||||
|
// that we don't crash or throw, check that the toString is a function, and
|
||||||
|
// also that the return value of toString is a string.
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, "toString")) {
|
||||||
|
if (typeof obj.toString === "function") {
|
||||||
|
const str = obj.toString();
|
||||||
|
if (typeof str === "string") {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If the object does not have a custom toString, attempt to perform a
|
// If the object does not have a custom toString, attempt to perform a
|
||||||
// JSON.stringify.
|
// JSON.stringify. We use a lot of bigints in libskynet, and calling
|
||||||
|
// JSON.stringify on an object with a bigint will cause a throw, so we add
|
||||||
|
// some custom handling to allow bigint objects to still be encoded.
|
||||||
try {
|
try {
|
||||||
return JSON.stringify(obj);
|
return JSON.stringify(obj, (_, v) => {
|
||||||
|
if (typeof v === "bigint") {
|
||||||
|
return v.toString();
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch {
|
catch (err) {
|
||||||
|
if (err !== undefined && typeof err.message === "string") {
|
||||||
|
return `[stringify failed]: ${err.message}`;
|
||||||
|
}
|
||||||
return "[stringify failed]";
|
return "[stringify failed]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// addContextToErr is a helper function that standardizes the formatting of
|
// addContextToErr is a helper function that standardizes the formatting of
|
||||||
// adding context to an error. Within the world of go we discovered that being
|
// adding context to an error.
|
||||||
// persistent about layering context onto errors is helpful when debugging,
|
|
||||||
// even though it often creates rather verbose error messages.
|
|
||||||
//
|
|
||||||
// addContextToErr will return null if the input err is null.
|
|
||||||
//
|
//
|
||||||
// NOTE: To protect against accidental situations where an Error type or some
|
// NOTE: To protect against accidental situations where an Error type or some
|
||||||
// other type is provided instead of a string, we wrap both of the inputs with
|
// other type is provided instead of a string, we wrap both of the inputs with
|
||||||
// tryStringify before returning them. This prevents runtime failures.
|
// objAsString before returning them. This prevents runtime failures.
|
||||||
function addContextToErr$1(err, context) {
|
function addContextToErr$1(err, context) {
|
||||||
if (err === null) {
|
if (err === null || err === undefined) {
|
||||||
err = "[no error provided]";
|
err = "[no error provided]";
|
||||||
}
|
}
|
||||||
return tryStringify$1(context) + ": " + tryStringify$1(err);
|
return objAsString(context) + ": " + objAsString(err);
|
||||||
}
|
|
||||||
// composeErr takes a series of inputs and composes them into a single string.
|
|
||||||
// Each element will be separated by a newline. If the input is not a string,
|
|
||||||
// it will be transformed into a string with JSON.stringify.
|
|
||||||
//
|
|
||||||
// Any object that cannot be stringified will be skipped, though an error will
|
|
||||||
// be logged.
|
|
||||||
function composeErr$1(...inputs) {
|
|
||||||
let result = "";
|
|
||||||
let resultEmpty = true;
|
|
||||||
for (let i = 0; i < inputs.length; i++) {
|
|
||||||
if (inputs[i] === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (resultEmpty) {
|
|
||||||
resultEmpty = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result += "\n";
|
|
||||||
}
|
|
||||||
result += tryStringify$1(inputs[i]);
|
|
||||||
}
|
|
||||||
if (resultEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper consts to make it easy to return empty values alongside errors.
|
const MAX_UINT_64 = 18446744073709551615n;
|
||||||
const nu8$7 = new Uint8Array(0);
|
|
||||||
// bufToB64 will convert a Uint8Array to a base64 string with URL encoding and
|
// bufToB64 will convert a Uint8Array to a base64 string with URL encoding and
|
||||||
// no padding characters.
|
// no padding characters.
|
||||||
function bufToB64$1(buf) {
|
function bufToB64$1(buf) {
|
||||||
let b64Str = btoa(String.fromCharCode.apply(null, buf));
|
const b64Str = btoa(String.fromCharCode(...buf));
|
||||||
return b64Str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
return b64Str.replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
||||||
}
|
}
|
||||||
// encodeU64 will encode a bigint in the range of a uint64 to an 8 byte
|
// encodeU64 will encode a bigint in the range of a uint64 to an 8 byte
|
||||||
// Uint8Array.
|
// Uint8Array.
|
||||||
function encodeU64$1(num) {
|
function encodeU64$1(num) {
|
||||||
// Check the bounds on the bigint.
|
// Check the bounds on the bigint.
|
||||||
if (num < 0) {
|
if (num < 0) {
|
||||||
return [nu8$7, "expected a positive integer"];
|
return [new Uint8Array(0), "expected a positive integer"];
|
||||||
}
|
}
|
||||||
if (num > 18446744073709551615n) {
|
if (num > MAX_UINT_64) {
|
||||||
return [nu8$7, "expected a number no larger than a uint64"];
|
return [new Uint8Array(0), "expected a number no larger than a uint64"];
|
||||||
}
|
}
|
||||||
// Encode the bigint into a Uint8Array.
|
// Encode the bigint into a Uint8Array.
|
||||||
let encoded = new Uint8Array(8);
|
const encoded = new Uint8Array(8);
|
||||||
for (let i = 0; i < encoded.length; i++) {
|
for (let i = 0; i < encoded.length; i++) {
|
||||||
let byte = Number(num & 0xffn);
|
const byte = Number(num & 0xffn);
|
||||||
encoded[i] = byte;
|
encoded[i] = byte;
|
||||||
num = num >> 8n;
|
num = num >> 8n;
|
||||||
}
|
}
|
||||||
return [encoded, null];
|
return [encoded, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
let gfi$1 = function (init) {
|
const gfi$1 = function (init) {
|
||||||
let i, r = new Float64Array(16);
|
let i;
|
||||||
|
const r = new Float64Array(16);
|
||||||
if (init)
|
if (init)
|
||||||
for (i = 0; i < init.length; i++)
|
for (i = 0; i < init.length; i++)
|
||||||
r[i] = init[i];
|
r[i] = init[i];
|
||||||
|
@ -161,6 +162,38 @@
|
||||||
0x2480, 0x2b83,
|
0x2480, 0x2b83,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// checkObj take an untrusted object and a list of typechecks to perform and
|
||||||
|
// will check that the object adheres to the typechecks. If a type is missing
|
||||||
|
// or has the wrong type, an error will be returned. This is intended to be
|
||||||
|
// used to check untrusted objects after they get decoded from JSON. This is
|
||||||
|
// particularly useful when receiving objects from untrusted entities over the
|
||||||
|
// network or over postMessage.
|
||||||
|
//
|
||||||
|
// Below is an example object, followed by the call that you would make to
|
||||||
|
// checkObj to verify the object.
|
||||||
|
//
|
||||||
|
// const expectedObj = {
|
||||||
|
// aNum: 35,
|
||||||
|
// aStr: "hi",
|
||||||
|
// aBig: 10n,
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const err = checkObj(expectedObj, [
|
||||||
|
// ["aNum", "number"],
|
||||||
|
// ["aStr", "string"],
|
||||||
|
// ["aBig", "bigint"],
|
||||||
|
// ]);
|
||||||
|
function checkObj(obj, checks) {
|
||||||
|
for (let i = 0; i < checks.length; i++) {
|
||||||
|
const check = checks[i];
|
||||||
|
const type = typeof obj[check[0]];
|
||||||
|
if (type !== check[1]) {
|
||||||
|
return "check failed, expecting " + check[1] + " got " + type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the queryMap.
|
// Create the queryMap.
|
||||||
let queries = {};
|
let queries = {};
|
||||||
// Define the nonce handling. nonceSeed is 16 random bytes that get generated
|
// Define the nonce handling. nonceSeed is 16 random bytes that get generated
|
||||||
|
@ -236,7 +269,12 @@
|
||||||
// at a minimum is working.
|
// at a minimum is working.
|
||||||
if (initResolved === false) {
|
if (initResolved === false) {
|
||||||
initResolved = true;
|
initResolved = true;
|
||||||
initResolve();
|
// We can't actually establish that init is complete until the
|
||||||
|
// kernel source has been set. This happens async and might happen
|
||||||
|
// after we receive the auth message.
|
||||||
|
sourcePromise.then(() => {
|
||||||
|
initResolve();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// If the auth status message says that login is complete, it means
|
// If the auth status message says that login is complete, it means
|
||||||
// that the user is logged in.
|
// that the user is logged in.
|
||||||
|
@ -314,6 +352,7 @@
|
||||||
kernelSource = iframe.contentWindow;
|
kernelSource = iframe.contentWindow;
|
||||||
kernelOrigin = "https://skt.us";
|
kernelOrigin = "https://skt.us";
|
||||||
kernelAuthLocation = "https://skt.us/auth.html";
|
kernelAuthLocation = "https://skt.us/auth.html";
|
||||||
|
sourceResolve();
|
||||||
// Set a timer to fail the login process if the kernel doesn't load in
|
// Set a timer to fail the login process if the kernel doesn't load in
|
||||||
// time.
|
// time.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -355,6 +394,7 @@
|
||||||
kernelOrigin = window.origin;
|
kernelOrigin = window.origin;
|
||||||
kernelAuthLocation = "http://kernel.skynet/auth.html";
|
kernelAuthLocation = "http://kernel.skynet/auth.html";
|
||||||
console.log("established connection to bridge, using browser extension for kernel");
|
console.log("established connection to bridge, using browser extension for kernel");
|
||||||
|
sourceResolve();
|
||||||
});
|
});
|
||||||
// Add the handler to the queries map.
|
// Add the handler to the queries map.
|
||||||
let nonce = nextNonce();
|
let nonce = nextNonce();
|
||||||
|
@ -399,6 +439,8 @@
|
||||||
let kernelLoadedPromise;
|
let kernelLoadedPromise;
|
||||||
let logoutResolve;
|
let logoutResolve;
|
||||||
let logoutPromise;
|
let logoutPromise;
|
||||||
|
let sourceResolve;
|
||||||
|
let sourcePromise; // resolves when the source is known and set
|
||||||
function init() {
|
function init() {
|
||||||
// If init has already been called, just return the init promise.
|
// If init has already been called, just return the init promise.
|
||||||
if (initialized === true) {
|
if (initialized === true) {
|
||||||
|
@ -422,6 +464,9 @@
|
||||||
logoutPromise = new Promise((resolve) => {
|
logoutPromise = new Promise((resolve) => {
|
||||||
logoutResolve = resolve;
|
logoutResolve = resolve;
|
||||||
});
|
});
|
||||||
|
sourcePromise = new Promise((resolve) => {
|
||||||
|
sourceResolve = resolve;
|
||||||
|
});
|
||||||
// Return the initPromise, which will resolve when bootloader init is
|
// Return the initPromise, which will resolve when bootloader init is
|
||||||
// complete.
|
// complete.
|
||||||
return initPromise;
|
return initPromise;
|
||||||
|
@ -430,7 +475,7 @@
|
||||||
// module identifier (typically a skylink), the second input is the method
|
// module identifier (typically a skylink), the second input is the method
|
||||||
// being called on the module, and the final input is optional and contains
|
// being called on the module, and the final input is optional and contains
|
||||||
// input data to be passed to the module. The input data will depend on the
|
// input data to be passed to the module. The input data will depend on the
|
||||||
// module and the method that is being called. The return value is an errTuple
|
// module and the method that is being called. The return value is an ErrTuple
|
||||||
// that contains the module's response. The format of the response is an
|
// that contains the module's response. The format of the response is an
|
||||||
// arbitrary object whose fields depend on the module and method being called.
|
// arbitrary object whose fields depend on the module and method being called.
|
||||||
//
|
//
|
||||||
|
@ -461,7 +506,7 @@
|
||||||
// as the receiveUpdate function, it's an arbitrary object whose fields depend
|
// as the receiveUpdate function, it's an arbitrary object whose fields depend
|
||||||
// on the module and method being queried.
|
// on the module and method being queried.
|
||||||
//
|
//
|
||||||
// The second return value is a promise that returns an errTuple. It will
|
// The second return value is a promise that returns an ErrTuple. It will
|
||||||
// resolve when the module sends a response message, and works the same as the
|
// resolve when the module sends a response message, and works the same as the
|
||||||
// return value of callModule.
|
// return value of callModule.
|
||||||
function connectModule(module, method, data, receiveUpdate) {
|
function connectModule(module, method, data, receiveUpdate) {
|
||||||
|
@ -540,16 +585,14 @@
|
||||||
// kernel provides a 'response' message. The other is for internal use and
|
// kernel provides a 'response' message. The other is for internal use and
|
||||||
// will resolve once the query has been created.
|
// will resolve once the query has been created.
|
||||||
let p;
|
let p;
|
||||||
let queryCreated;
|
let haveQueryCreated = new Promise((queryCreatedResolve) => {
|
||||||
let haveQueryCreated = new Promise((resolve) => {
|
|
||||||
queryCreated = resolve;
|
|
||||||
p = new Promise((resolve) => {
|
p = new Promise((resolve) => {
|
||||||
getNonce.then((nonce) => {
|
getNonce.then((nonce) => {
|
||||||
queries[nonce] = { resolve };
|
queries[nonce] = { resolve };
|
||||||
if (receiveUpdate !== null && receiveUpdate !== undefined) {
|
if (receiveUpdate !== null && receiveUpdate !== undefined) {
|
||||||
queries[nonce]["receiveUpdate"] = receiveUpdate;
|
queries[nonce]["receiveUpdate"] = receiveUpdate;
|
||||||
}
|
}
|
||||||
queryCreated(nonce);
|
queryCreatedResolve(nonce);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -653,6 +696,10 @@
|
||||||
// logoutComplete() will block until auth has reached stage 4. libkernel does
|
// logoutComplete() will block until auth has reached stage 4. libkernel does
|
||||||
// not support resetting the auth stages, once stage 4 has been reached the app
|
// not support resetting the auth stages, once stage 4 has been reached the app
|
||||||
// needs to refresh.
|
// needs to refresh.
|
||||||
|
// loginComplete will resolve when the user has successfully logged in.
|
||||||
|
function loginComplete() {
|
||||||
|
return loginPromise;
|
||||||
|
}
|
||||||
// kernelLoaded will resolve when the user has successfully loaded the kernel.
|
// kernelLoaded will resolve when the user has successfully loaded the kernel.
|
||||||
// If there was an error in loading the kernel, the error will be returned.
|
// If there was an error in loading the kernel, the error will be returned.
|
||||||
//
|
//
|
||||||
|
@ -660,10 +707,6 @@
|
||||||
function kernelLoaded() {
|
function kernelLoaded() {
|
||||||
return kernelLoadedPromise;
|
return kernelLoadedPromise;
|
||||||
}
|
}
|
||||||
// loginComplete will resolve when the user has successfully logged in.
|
|
||||||
function loginComplete() {
|
|
||||||
return loginPromise;
|
|
||||||
}
|
|
||||||
// logoutComplete will resolve when the user has logged out. Note that
|
// logoutComplete will resolve when the user has logged out. Note that
|
||||||
// logoutComplete will only resolve if the user logged in first - if the user
|
// logoutComplete will only resolve if the user logged in first - if the user
|
||||||
// was not logged in to begin with, this promise will not resolve.
|
// was not logged in to begin with, this promise will not resolve.
|
||||||
|
@ -718,12 +761,27 @@
|
||||||
// because the object is relatively complex and all of the fields are more or
|
// because the object is relatively complex and all of the fields are more or
|
||||||
// less required.
|
// less required.
|
||||||
function registryRead(publicKey, dataKey) {
|
function registryRead(publicKey, dataKey) {
|
||||||
let registryModule = "AQCovesg1AXUzKXLeRzQFILbjYMKr_rvNLsNhdq5GbYb2Q";
|
return new Promise((resolve) => {
|
||||||
let data = {
|
let registryModule = "AQCovesg1AXUzKXLeRzQFILbjYMKr_rvNLsNhdq5GbYb2Q";
|
||||||
publicKey,
|
let data = {
|
||||||
dataKey,
|
publicKey,
|
||||||
};
|
dataKey,
|
||||||
return callModule(registryModule, "readEntry", data);
|
};
|
||||||
|
callModule(registryModule, "readEntry", data).then(([result, err]) => {
|
||||||
|
if (err !== null) {
|
||||||
|
resolve([{}, addContextToErr$1(err, "readEntry module call failed")]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve([
|
||||||
|
{
|
||||||
|
exists: result.exists,
|
||||||
|
entryData: result.entryData,
|
||||||
|
revision: result.revision,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// registryWrite will perform a registry write on a portal.
|
// registryWrite will perform a registry write on a portal.
|
||||||
//
|
//
|
||||||
|
@ -807,7 +865,7 @@
|
||||||
init: init,
|
init: init,
|
||||||
newKernelQuery: newKernelQuery,
|
newKernelQuery: newKernelQuery,
|
||||||
addContextToErr: addContextToErr$1,
|
addContextToErr: addContextToErr$1,
|
||||||
composeErr: composeErr$1
|
checkObj: checkObj
|
||||||
});
|
});
|
||||||
|
|
||||||
var require$$0 = /*@__PURE__*/getAugmentedNamespace(dist$1);
|
var require$$0 = /*@__PURE__*/getAugmentedNamespace(dist$1);
|
||||||
|
|
Loading…
Reference in New Issue