*Prune out old or unneeded code, some maybe be refactored back in as plugins or in a different form
ci/woodpecker/push/woodpecker Pipeline failed
Details
ci/woodpecker/push/woodpecker Pipeline failed
Details
This commit is contained in:
parent
6fa5ccd49a
commit
457398b291
|
@ -31,7 +31,6 @@ config.inject({
|
||||||
logLevel: "info",
|
logLevel: "info",
|
||||||
pluginDir: path.resolve(configDir, "..", "plugins"),
|
pluginDir: path.resolve(configDir, "..", "plugins"),
|
||||||
plugins: ["core"],
|
plugins: ["core"],
|
||||||
ssl: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
config.load({
|
config.load({
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { start as startApp } from "./modules/app";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import config from "./config.js";
|
import config from "./config.js";
|
||||||
import { loadPlugins } from "./modules/plugin.js";
|
import { loadPlugins } from "./modules/plugin.js";
|
||||||
import { start as startSSl } from "./modules/ssl.js";
|
|
||||||
import { start as startSwarm } from "./modules/swarm.js";
|
import { start as startSwarm } from "./modules/swarm.js";
|
||||||
import * as bip39 from "@scure/bip39";
|
import * as bip39 from "@scure/bip39";
|
||||||
import { wordlist } from "@scure/bip39/wordlists/english";
|
import { wordlist } from "@scure/bip39/wordlists/english";
|
||||||
|
@ -22,7 +21,6 @@ async function boot() {
|
||||||
await loadPlugins();
|
await loadPlugins();
|
||||||
await startApp();
|
await startApp();
|
||||||
await startRpc();
|
await startRpc();
|
||||||
await startSSl();
|
|
||||||
await startRelay();
|
await startRelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
445
src/lib/file.ts
445
src/lib/file.ts
|
@ -1,445 +0,0 @@
|
||||||
import type { Err, progressiveFetchResult } from "libskynet";
|
|
||||||
// @ts-ignore
|
|
||||||
import { SkynetClient } from "@skynetlabs/skynet-nodejs";
|
|
||||||
import type {
|
|
||||||
IndependentFileSmall,
|
|
||||||
IndependentFileSmallMetadata,
|
|
||||||
} from "@lumeweb/relay-types";
|
|
||||||
import {
|
|
||||||
addContextToErr,
|
|
||||||
blake2b,
|
|
||||||
bufToHex,
|
|
||||||
ed25519Sign,
|
|
||||||
encodePrefixedBytes,
|
|
||||||
encodeU64,
|
|
||||||
defaultPortalList,
|
|
||||||
skylinkToResolverEntryData,
|
|
||||||
encryptFileSmall,
|
|
||||||
decryptFileSmall,
|
|
||||||
entryIDToSkylink,
|
|
||||||
deriveRegistryEntryID,
|
|
||||||
taggedRegistryEntryKeys,
|
|
||||||
namespaceInode,
|
|
||||||
deriveChildSeed,
|
|
||||||
bufToB64,
|
|
||||||
} from "libskynet";
|
|
||||||
|
|
||||||
import { readRegistryEntry, progressiveFetch, upload } from "libskynetnode";
|
|
||||||
|
|
||||||
const ERR_NOT_EXISTS = "DNE";
|
|
||||||
const STD_FILENAME = "file";
|
|
||||||
|
|
||||||
async function overwriteRegistryEntry(
|
|
||||||
keypair: any,
|
|
||||||
datakey: Uint8Array,
|
|
||||||
data: Uint8Array,
|
|
||||||
revision: bigint
|
|
||||||
): Promise<null> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (data.length > 86) {
|
|
||||||
reject("provided data is too large to fit in a registry entry");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [encodedRevision, errU64] = encodeU64(revision);
|
|
||||||
if (errU64 !== null) {
|
|
||||||
reject(addContextToErr(errU64, "unable to encode revision number"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let datakeyHex = bufToHex(datakey);
|
|
||||||
let [encodedData, errEPB] = encodePrefixedBytes(data);
|
|
||||||
if (errEPB !== null) {
|
|
||||||
reject(addContextToErr(errEPB, "unable to encode the registry data"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let dataToSign = new Uint8Array(32 + 8 + data.length + 8);
|
|
||||||
dataToSign.set(datakey, 0);
|
|
||||||
dataToSign.set(encodedData, 32);
|
|
||||||
dataToSign.set(encodedRevision, 32 + 8 + data.length);
|
|
||||||
let sigHash = blake2b(dataToSign);
|
|
||||||
let [sig, errS] = ed25519Sign(sigHash, keypair.secretKey);
|
|
||||||
if (errS !== null) {
|
|
||||||
reject(addContextToErr(errS, "unable to produce signature"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let postBody = {
|
|
||||||
publickey: {
|
|
||||||
algorithm: "ed25519",
|
|
||||||
key: Array.from(keypair.publicKey),
|
|
||||||
},
|
|
||||||
datakey: datakeyHex,
|
|
||||||
revision: Number(revision),
|
|
||||||
data: Array.from(data),
|
|
||||||
signature: Array.from(sig),
|
|
||||||
};
|
|
||||||
let fetchOpts = {
|
|
||||||
method: "post",
|
|
||||||
body: JSON.stringify(postBody),
|
|
||||||
};
|
|
||||||
let endpoint = "/skynet/registry";
|
|
||||||
|
|
||||||
progressiveFetch(
|
|
||||||
endpoint,
|
|
||||||
fetchOpts,
|
|
||||||
defaultPortalList,
|
|
||||||
verifyRegistryWrite
|
|
||||||
).then((result: progressiveFetchResult) => {
|
|
||||||
if (result.success === true) {
|
|
||||||
resolve(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reject("unable to write registry entry\n" + JSON.stringify(result));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async function verifyRegistryWrite(response: Response): Promise<Err> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
if (!("status" in response)) {
|
|
||||||
resolve("response did not contain a status");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (response.status === 204) {
|
|
||||||
resolve(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve("unrecognized status");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createIndependentFileSmall(
|
|
||||||
seed: Uint8Array,
|
|
||||||
userInode: string,
|
|
||||||
fileData: Uint8Array
|
|
||||||
): Promise<[IndependentFileSmall, Err]> {
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
let [inode, errNI] = namespaceInode("IndependentFileSmall", userInode);
|
|
||||||
if (errNI !== null) {
|
|
||||||
resolve([{} as any, addContextToErr(errNI, "unable to namespace inode")]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [keypair, dataKey, errTREK] = taggedRegistryEntryKeys(
|
|
||||||
seed,
|
|
||||||
inode,
|
|
||||||
inode
|
|
||||||
);
|
|
||||||
if (errTREK !== null) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(
|
|
||||||
errTREK,
|
|
||||||
"unable to get registry entry for provided inode"
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result;
|
|
||||||
try {
|
|
||||||
result = await readRegistryEntry(keypair.publicKey, dataKey);
|
|
||||||
} catch (e) {
|
|
||||||
result = { exists: false };
|
|
||||||
}
|
|
||||||
if (result.exists === true) {
|
|
||||||
resolve([{} as any, "exists"]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encryptionKey = deriveChildSeed(seed, inode);
|
|
||||||
let metadata: IndependentFileSmallMetadata = {
|
|
||||||
largestHistoricSize: BigInt(fileData.length),
|
|
||||||
};
|
|
||||||
|
|
||||||
let revisionSeed = new Uint8Array(seed.length + 8);
|
|
||||||
revisionSeed.set(seed, 0);
|
|
||||||
let revisionKey = deriveChildSeed(revisionSeed, inode);
|
|
||||||
let revision = BigInt(revisionKey[0]) * 256n + BigInt(revisionKey[1]);
|
|
||||||
let [encryptedData, errEF] = encryptFileSmall(
|
|
||||||
encryptionKey,
|
|
||||||
inode,
|
|
||||||
revision,
|
|
||||||
metadata,
|
|
||||||
fileData,
|
|
||||||
metadata.largestHistoricSize
|
|
||||||
);
|
|
||||||
if (errEF !== null) {
|
|
||||||
resolve([{} as any, addContextToErr(errEF, "unable to encrypt file")]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let immutableSkylink;
|
|
||||||
|
|
||||||
try {
|
|
||||||
immutableSkylink = await upload(encryptedData, {
|
|
||||||
Filename: STD_FILENAME,
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
resolve([{} as any, addContextToErr(e, "upload failed")]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [entryData, errSTRED] = skylinkToResolverEntryData(immutableSkylink);
|
|
||||||
if (errSTRED !== null) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(
|
|
||||||
errSTRED,
|
|
||||||
"couldn't create resovler link from upload skylink"
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await overwriteRegistryEntry(keypair, dataKey, entryData, revision);
|
|
||||||
} catch (e: any) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(e, "could not write to registry entry"),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [entryID, errDREID] = deriveRegistryEntryID(keypair.publicKey, dataKey);
|
|
||||||
if (errDREID !== null) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(errDREID, "could not compute entry id"),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let skylink = entryIDToSkylink(entryID);
|
|
||||||
|
|
||||||
let encStr = bufToB64(encryptionKey);
|
|
||||||
let viewKey = encStr + inode;
|
|
||||||
|
|
||||||
let ifile: IndependentFileSmall = {
|
|
||||||
dataKey,
|
|
||||||
fileData,
|
|
||||||
inode,
|
|
||||||
keypair,
|
|
||||||
metadata,
|
|
||||||
revision,
|
|
||||||
seed,
|
|
||||||
|
|
||||||
skylink,
|
|
||||||
viewKey,
|
|
||||||
|
|
||||||
overwriteData: function (newData: Uint8Array): Promise<Err> {
|
|
||||||
return overwriteIndependentFileSmall(ifile, newData);
|
|
||||||
},
|
|
||||||
readData: function (): Promise<[Uint8Array, Err]> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
let data = new Uint8Array(ifile.fileData.length);
|
|
||||||
data.set(ifile.fileData, 0);
|
|
||||||
resolve([data, null]);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
resolve([ifile, null]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function openIndependentFileSmall(
|
|
||||||
seed: Uint8Array,
|
|
||||||
userInode: string
|
|
||||||
): Promise<[IndependentFileSmall, Err]> {
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
let [inode, errNI] = namespaceInode("IndependentFileSmall", userInode);
|
|
||||||
if (errNI !== null) {
|
|
||||||
resolve([{} as any, addContextToErr(errNI, "unable to namespace inode")]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [keypair, dataKey, errTREK] = taggedRegistryEntryKeys(
|
|
||||||
seed,
|
|
||||||
inode,
|
|
||||||
inode
|
|
||||||
);
|
|
||||||
if (errTREK !== null) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(
|
|
||||||
errTREK,
|
|
||||||
"unable to get registry entry for provided inode"
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result;
|
|
||||||
try {
|
|
||||||
result = await readRegistryEntry(keypair.publicKey, dataKey);
|
|
||||||
} catch (e: any) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(e, "unable to read registry entry for file"),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (result.exists !== true) {
|
|
||||||
resolve([{} as any, ERR_NOT_EXISTS]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [entryID, errDREID] = deriveRegistryEntryID(keypair.publicKey, dataKey);
|
|
||||||
if (errDREID !== null) {
|
|
||||||
resolve([
|
|
||||||
{} as any,
|
|
||||||
addContextToErr(errDREID, "unable to derive registry entry id"),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let skylink = entryIDToSkylink(entryID);
|
|
||||||
|
|
||||||
const client = new SkynetClient("https://web3portal.com");
|
|
||||||
let encryptedData;
|
|
||||||
try {
|
|
||||||
encryptedData = await client.downloadData(skylink);
|
|
||||||
} catch (e: any) {
|
|
||||||
resolve([{} as any, addContextToErr(e, "unable to download file")]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encryptionKey = deriveChildSeed(seed, inode);
|
|
||||||
let [metadata, fileData, errDF] = decryptFileSmall(
|
|
||||||
encryptionKey,
|
|
||||||
inode,
|
|
||||||
encryptedData
|
|
||||||
);
|
|
||||||
if (errDF !== null) {
|
|
||||||
resolve([{} as any, addContextToErr(errDF, "unable to decrypt file")]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encStr = bufToB64(encryptionKey);
|
|
||||||
let viewKey = encStr + inode;
|
|
||||||
|
|
||||||
let ifile: IndependentFileSmall = {
|
|
||||||
dataKey,
|
|
||||||
fileData,
|
|
||||||
inode,
|
|
||||||
keypair,
|
|
||||||
metadata,
|
|
||||||
revision: result.revision!,
|
|
||||||
seed,
|
|
||||||
|
|
||||||
skylink,
|
|
||||||
viewKey,
|
|
||||||
|
|
||||||
overwriteData: function (newData: Uint8Array): Promise<Err> {
|
|
||||||
return overwriteIndependentFileSmall(ifile, newData);
|
|
||||||
},
|
|
||||||
|
|
||||||
readData: function (): Promise<[Uint8Array, Err]> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
let data = new Uint8Array(ifile.fileData.length);
|
|
||||||
data.set(ifile.fileData, 0);
|
|
||||||
resolve([data, null]);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
resolve([ifile, null]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async function overwriteIndependentFileSmall(
|
|
||||||
file: IndependentFileSmall,
|
|
||||||
newData: Uint8Array
|
|
||||||
): Promise<Err> {
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
// Create a new metadata for the file based on the current file
|
|
||||||
// metadata. Need to update the largest historic size.
|
|
||||||
let newMetadata: IndependentFileSmallMetadata = {
|
|
||||||
largestHistoricSize: BigInt(file.metadata.largestHistoricSize),
|
|
||||||
};
|
|
||||||
if (BigInt(newData.length) > newMetadata.largestHistoricSize) {
|
|
||||||
newMetadata.largestHistoricSize = BigInt(newData.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the new revision number for the file. This is done
|
|
||||||
// deterministically using the seed and the current revision number, so
|
|
||||||
// that multiple concurrent updates will end up with the same revision.
|
|
||||||
// We use a random number between 1 and 256 for our increment.
|
|
||||||
let [encodedRevision, errEU64] = encodeU64(file.revision);
|
|
||||||
if (errEU64 !== null) {
|
|
||||||
resolve(addContextToErr(errEU64, "unable to encode revision"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let revisionSeed = new Uint8Array(
|
|
||||||
file.seed.length + encodedRevision.length
|
|
||||||
);
|
|
||||||
revisionSeed.set(file.seed, 0);
|
|
||||||
revisionSeed.set(encodedRevision, file.seed.length);
|
|
||||||
let revisionKey = deriveChildSeed(revisionSeed, file.inode);
|
|
||||||
let newRevision = file.revision + BigInt(revisionKey[0]) + 1n;
|
|
||||||
|
|
||||||
// Get the encryption key.
|
|
||||||
let encryptionKey = deriveChildSeed(file.seed, file.inode);
|
|
||||||
|
|
||||||
// Create a new encrypted blob for the data.
|
|
||||||
//
|
|
||||||
// NOTE: Need to supply the data that would be in place after a
|
|
||||||
// successful update, which means using the new metadata and revision
|
|
||||||
// number.
|
|
||||||
let [encryptedData, errEFS] = encryptFileSmall(
|
|
||||||
encryptionKey,
|
|
||||||
file.inode,
|
|
||||||
newRevision,
|
|
||||||
newMetadata,
|
|
||||||
newData,
|
|
||||||
newMetadata.largestHistoricSize
|
|
||||||
);
|
|
||||||
if (errEFS !== null) {
|
|
||||||
resolve(addContextToErr(errEFS, "unable to encrypt updated file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload the data to get the immutable link.
|
|
||||||
let skylink;
|
|
||||||
try {
|
|
||||||
skylink = await upload(encryptedData, {
|
|
||||||
Filename: STD_FILENAME,
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
resolve(addContextToErr(e, "new data upload failed"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write to the registry entry.
|
|
||||||
let [entryData, errSTRED] = skylinkToResolverEntryData(skylink);
|
|
||||||
if (errSTRED !== null) {
|
|
||||||
resolve(
|
|
||||||
addContextToErr(
|
|
||||||
errSTRED,
|
|
||||||
"could not create resolver link from upload skylink"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await overwriteRegistryEntry(
|
|
||||||
file.keypair,
|
|
||||||
file.dataKey,
|
|
||||||
entryData,
|
|
||||||
newRevision
|
|
||||||
);
|
|
||||||
} catch (e: any) {
|
|
||||||
resolve(addContextToErr(e, "could not write to registry entry"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// File update was successful, update the file metadata.
|
|
||||||
file.revision = newRevision;
|
|
||||||
file.metadata = newMetadata;
|
|
||||||
file.fileData = newData;
|
|
||||||
resolve(null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
createIndependentFileSmall,
|
|
||||||
openIndependentFileSmall,
|
|
||||||
overwriteIndependentFileSmall,
|
|
||||||
};
|
|
|
@ -1,151 +0,0 @@
|
||||||
import tls from "tls";
|
|
||||||
import {
|
|
||||||
createIndependentFileSmall,
|
|
||||||
openIndependentFileSmall,
|
|
||||||
overwriteIndependentFileSmall,
|
|
||||||
} from "../lib/file.js";
|
|
||||||
// @ts-ignore
|
|
||||||
import promiseRetry from "promise-retry";
|
|
||||||
import config from "../config.js";
|
|
||||||
import log from "loglevel";
|
|
||||||
import { getSeed } from "../lib/seed.js";
|
|
||||||
import type {
|
|
||||||
IndependentFileSmall,
|
|
||||||
SavedSslData,
|
|
||||||
SslData,
|
|
||||||
} from "@lumeweb/relay-types";
|
|
||||||
|
|
||||||
let sslCtx: tls.SecureContext = tls.createSecureContext();
|
|
||||||
let sslObject: SslData = {};
|
|
||||||
let sslChecker: () => Promise<void>;
|
|
||||||
|
|
||||||
const FILE_CERT_NAME = "/lumeweb/relay/ssl.crt";
|
|
||||||
const FILE_KEY_NAME = "/lumeweb/relay/ssl.key";
|
|
||||||
|
|
||||||
export function setSslContext(context: tls.SecureContext) {
|
|
||||||
sslCtx = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSslContext(): tls.SecureContext {
|
|
||||||
return sslCtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setSsl(
|
|
||||||
cert: IndependentFileSmall | Uint8Array,
|
|
||||||
key: IndependentFileSmall | Uint8Array
|
|
||||||
): void {
|
|
||||||
cert = (cert as IndependentFileSmall)?.fileData || cert;
|
|
||||||
key = (key as IndependentFileSmall)?.fileData || key;
|
|
||||||
sslObject.cert = cert as Uint8Array;
|
|
||||||
sslObject.key = key as Uint8Array;
|
|
||||||
setSslContext(
|
|
||||||
tls.createSecureContext({
|
|
||||||
cert: Buffer.from(cert),
|
|
||||||
key: Buffer.from(key),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSsl(): SslData {
|
|
||||||
return sslObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function saveSSl(): Promise<void> {
|
|
||||||
const seed = getSeed();
|
|
||||||
|
|
||||||
log.info(`Saving SSL Certificate for ${config.str("domain")}`);
|
|
||||||
|
|
||||||
let oldCert = await getSslCert();
|
|
||||||
let cert: any = getSsl()?.cert;
|
|
||||||
if (oldCert) {
|
|
||||||
await overwriteIndependentFileSmall(
|
|
||||||
oldCert as IndependentFileSmall,
|
|
||||||
Buffer.from(cert)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await createIndependentFileSmall(seed, FILE_CERT_NAME, Buffer.from(cert));
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldKey = await getSslKey();
|
|
||||||
let key: any = getSsl()?.key;
|
|
||||||
|
|
||||||
if (oldKey) {
|
|
||||||
await overwriteIndependentFileSmall(
|
|
||||||
oldKey as IndependentFileSmall,
|
|
||||||
Buffer.from(key)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await createIndependentFileSmall(seed, FILE_KEY_NAME, Buffer.from(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`Saved SSL Certificate for ${config.str("domain")}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getSavedSsl(
|
|
||||||
retry = true
|
|
||||||
): Promise<boolean | SavedSslData> {
|
|
||||||
let retryOptions = retry ? {} : { retries: 0 };
|
|
||||||
let sslCert: IndependentFileSmall | boolean = false;
|
|
||||||
let sslKey: IndependentFileSmall | boolean = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await promiseRetry(async (retry: any) => {
|
|
||||||
sslCert = await getSslCert();
|
|
||||||
if (!sslCert) {
|
|
||||||
retry();
|
|
||||||
}
|
|
||||||
}, retryOptions);
|
|
||||||
|
|
||||||
await promiseRetry(async (retry: any) => {
|
|
||||||
sslKey = await getSslKey();
|
|
||||||
if (!sslKey) {
|
|
||||||
retry();
|
|
||||||
}
|
|
||||||
}, retryOptions);
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
if (!sslCert || !sslKey) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
cert: sslCert as IndependentFileSmall,
|
|
||||||
key: sslKey as IndependentFileSmall,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSslCert(): Promise<IndependentFileSmall | boolean> {
|
|
||||||
return getSslFile(FILE_CERT_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSslKey(): Promise<IndependentFileSmall | boolean> {
|
|
||||||
return getSslFile(FILE_KEY_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSslFile(
|
|
||||||
name: string
|
|
||||||
): Promise<IndependentFileSmall | boolean> {
|
|
||||||
let seed = getSeed();
|
|
||||||
|
|
||||||
let [file, err] = await openIndependentFileSmall(seed, name);
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setSSlCheck(checker: () => Promise<void>): void {
|
|
||||||
sslChecker = checker;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSslCheck(): () => Promise<void> {
|
|
||||||
return sslChecker;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function start() {
|
|
||||||
if (config.bool("ssl") && getSslCheck()) {
|
|
||||||
await getSslCheck()();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue