206 lines
No EOL
6.3 KiB
JavaScript
206 lines
No EOL
6.3 KiB
JavaScript
import apfetch from "./auth-fetch.js";
|
|
import * as sdk from "matrix-js-sdk";
|
|
import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
|
|
import { VerificationPhase, VerificationRequestEvent, VerifierEvent } from "matrix-js-sdk/lib/crypto-api.js";
|
|
import sdkExt from "./lib/ext.js";
|
|
import { resolve } from "node:path";
|
|
import fs from "node:fs";
|
|
import { LocalStorage } from 'node-localstorage';
|
|
|
|
import fetch from "node-fetch";
|
|
global.fetch = fetch;
|
|
|
|
import Olm from "@matrix-org/olm";
|
|
global.Olm = Olm;
|
|
|
|
import env from "dotenv";
|
|
env.config();
|
|
|
|
const localStorage = new LocalStorage("./data/localstorage");
|
|
const cryptoStore = new sdk.LocalStorageCryptoStore(localStorage);
|
|
const store = new sdk.MemoryStore({ localStorage });
|
|
|
|
var logger = {
|
|
trace: () => { },
|
|
debug: () => { },
|
|
info: () => { },
|
|
warn: () => { },
|
|
error: () => { },
|
|
}
|
|
|
|
const client = sdk.createClient({
|
|
baseUrl: process.env.BASE_URL,
|
|
accessToken: process.env.ACCESS_TOKEN,
|
|
deviceId: process.env.DEVICE_ID,
|
|
userId: process.env.USER_ID,
|
|
verificationMethods: [VerificationMethod.Sas],
|
|
logger: logger,
|
|
cryptoStore,
|
|
store
|
|
});
|
|
|
|
sdkExt(client);
|
|
|
|
apfetch(process.env.AP_FETCH_PORT);
|
|
|
|
var prefixes = [process.env.PREFIX];
|
|
client.initialized = false;
|
|
|
|
client.modules = [];
|
|
client.commands = [];
|
|
|
|
for (const file of fs.readdirSync(resolve("modules"))) {
|
|
try {
|
|
if (file.startsWith(".")) continue;
|
|
var module = (await import(resolve("modules", file))).default;
|
|
client.modules.push(module);
|
|
client.log("[load:modules]", `loaded ${module.name}`);
|
|
} catch (err) {
|
|
client.error("[load:modules]", `failed to load "${file}":\n`, err);
|
|
}
|
|
}
|
|
|
|
for (const file of fs.readdirSync(resolve("commands"))) {
|
|
try {
|
|
if (file.startsWith(".")) continue;
|
|
var command = (await import(resolve("commands", file))).default;
|
|
command.usage = process.env.PREFIX + command.command + (command.usage ? " " + command.usage : '');
|
|
client.commands.push(command);
|
|
client.log("[load:commands]", `loaded ${command.name}`);
|
|
} catch (err) {
|
|
client.error("[load:commands]", `failed to load "${file}":`, err);
|
|
}
|
|
}
|
|
|
|
function doModule(client, event) {
|
|
client.modules.forEach(m => {
|
|
if (!m) return;
|
|
|
|
var config = client.config.get(event.sender.roomId);
|
|
if (config.get(m.name) === false) return;
|
|
|
|
try {
|
|
m.hooks?.message(client, event);
|
|
} catch (err) {
|
|
client.log("[hook]", err);
|
|
}
|
|
});
|
|
}
|
|
|
|
function doCommand(client, event, cmd, args) {
|
|
var command;
|
|
command = client.commands.filter(c => c.command == cmd)[0];
|
|
if (!command)
|
|
return false;
|
|
|
|
if ((command.owner && event.sender.userId != process.env.OWNER_ID) || (command.minPwr && event.sender.powerLevel < command.minPwr && event.sender.userId != process.env.OWNER_ID)) {
|
|
var addl = command.minPwr ? `this command requires a power level of ${command.minPwr}\nyour power level is ${event.sender.powerLevel}` : "this command is owner-only.";
|
|
client.reply(event, addl, '<img src="mxc://nyx.ftp.sh/2kAXPyosdaz1M6Fv8t2V9SyxcJZEscdR" alt="nuh uh" /><br>' + addl.replaceAll("\n", "<br>"));
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
command.execute(client, event, args);
|
|
} catch (err) {
|
|
client.log("[cmd]", err);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
async function verifyCallback(request) {
|
|
console.log("### VERIFICATION ### Starting for " + request.otherUserId);
|
|
if (!request.initiatedByMe) {
|
|
await request.accept();
|
|
var verifier = await request.startVerification(VerificationMethod.Sas);
|
|
verifier.on(VerifierEvent.ShowSas, async function () {
|
|
console.log("### VERIFICATION ### Confirming");
|
|
await verifier.getShowSasCallbacks().confirm();
|
|
});
|
|
}
|
|
|
|
request.on(VerificationRequestEvent.Change, async function () {
|
|
switch (request.phase) {
|
|
case 3:
|
|
break;
|
|
case 4:
|
|
var verifier = await request.startVerification(VerificationMethod.Sas);
|
|
verifier.on(VerifierEvent.ShowSas, async function () {
|
|
console.log("### VERIFICATION ### Confirming");
|
|
await verifier.getShowSasCallbacks().confirm();
|
|
});
|
|
case 5:
|
|
console.log("### VERIFICATION ### Cancelled!");
|
|
case 6:
|
|
console.log("### VERIFICATION ### Done!");
|
|
break;
|
|
default:
|
|
console.log("### VERIFICATION ### " + request.phase);
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
client.once("sync", async function (state, prevState, data) {
|
|
if (state != "PREPARED") return;
|
|
client.setGlobalErrorOnUnknownDevices(false);
|
|
client.name = client._store.users[client.credentials.userId].displayName;
|
|
client.log("[sdk:sync]", "connected:", client.name);
|
|
prefixes.push(client.name + ": ");
|
|
prefixes.push(client.name + " ");
|
|
client.initialized = true;
|
|
|
|
while (!await client.getCrypto().isCrossSigningReady()) { }
|
|
var status = await client.getCrypto().getDeviceVerificationStatus(client.getUserId(), client.getDeviceId());
|
|
if (!status || Object.keys(status).map(v => status[v]).includes(false)) {
|
|
const request = await client.getCrypto().requestOwnUserVerification();
|
|
verifyCallback(request);
|
|
}
|
|
});
|
|
|
|
client.on(sdk.CryptoEvent.VerificationRequestReceived, verifyCallback);
|
|
|
|
client.on(sdk.RoomEvent.Timeline, async function (event, room, toStartOfTimeline) {
|
|
await client.decryptEventIfNeeded(event);
|
|
|
|
if (!client.initialized || toStartOfTimeline || event.getType() !== "m.room.message" || event.sender.userId == client.credentials.userId) {
|
|
return;
|
|
}
|
|
|
|
var content = event.getContent();
|
|
|
|
if (content["m.relates_to"] !== undefined)
|
|
content.body = content.body.substring(content.body.indexOf("\n\n") + 2);
|
|
|
|
event.sender = client.getRoom(event.sender.roomId).getMember(event.getSender());
|
|
var content = content.body;
|
|
var isCommand = false;
|
|
|
|
for (const prefix of prefixes) {
|
|
if (content.startsWith(prefix)) {
|
|
isCommand = true;
|
|
content = content.substring(prefix.length);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isCommand) {
|
|
doModule(client, event);
|
|
} else {
|
|
var args = content.split(/\s/g);
|
|
var cmd = args.shift();
|
|
args = content.substring(cmd.length + 1);
|
|
|
|
doCommand(client, event, cmd, args)
|
|
}
|
|
});
|
|
|
|
client.on("Room.myMembership", function (room, membership, prevMembership) {
|
|
if (membership === "invite") {
|
|
client.joinRoom(room.roomId).then(function () {
|
|
client.log("[client:autojoin] joined %s", room.roomId);
|
|
});
|
|
}
|
|
});
|
|
|
|
await client.initCrypto();
|
|
await client.startClient(); |