feat: complete Ancestor quote bot with production-ready Docker support

This commit is contained in:
unfunny
2026-09-13 14:14:38 -04:00
parent f2016da05a
commit fe7351a7dc
1145 changed files with 30890 additions and 97684 deletions

View File

@@ -1,4 +1,14 @@
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.initRustCrypto = initRustCrypto;
var RustSdkCryptoJs = _interopRequireWildcard(require("@matrix-org/matrix-sdk-crypto-wasm"));
var _rustCrypto = require("./rust-crypto");
var _logger = require("../logger");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
@@ -15,95 +25,35 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
import { StoreHandle } from "@matrix-org/matrix-sdk-crypto-wasm";
import { MAX_INVITE_ACCEPTANCE_MS_FOR_KEY_BUNDLE, RustCrypto } from "./rust-crypto.js";
import { MigrationState } from "../crypto/store/base.js";
import { migrateFromLegacyCrypto, migrateLegacyLocalTrustIfNeeded, migrateRoomSettingsFromLegacyCrypto } from "./libolm_migration.js";
/**
* The arguments used to initialise RustCrypto, passed in to initRustCrypto.
*
* @internal
*/
/**
* Create a new `RustCrypto` implementation
*
* @param args - InitRustCryptoArgs
* @param http - Low-level HTTP interface: used to make outgoing requests required by the rust SDK.
* We expect it to set the access token, etc.
* @param userId - The local user's User ID.
* @param deviceId - The local user's Device ID.
* @param secretStorage - Interface to server-side secret storage.
* @param cryptoCallbacks - Crypto callbacks provided by the application
* @param storePrefix - the prefix to use on the indexeddbs created by rust-crypto.
* If unset, a memory store will be used.
*
* @internal
*/
export async function initRustCrypto(args) {
const {
logger
} = args;
async function initRustCrypto(http, userId, deviceId, secretStorage, cryptoCallbacks, storePrefix) {
var _ref;
// initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done
logger.debug("Initialising Rust crypto-sdk WASM artifact");
await RustSdkCryptoJs.initAsync();
logger.debug("Opening Rust CryptoStore");
let storeHandle;
if (args.storePrefix) {
if (args.storeKey) {
storeHandle = await StoreHandle.openWithKey(args.storePrefix, args.storeKey, logger);
} else {
storeHandle = await StoreHandle.open(args.storePrefix, args.storePassphrase, logger);
}
} else {
storeHandle = await StoreHandle.open(null, null, logger);
}
if (args.legacyCryptoStore) {
// We have a legacy crypto store, which we may need to migrate from.
await migrateFromLegacyCrypto(_objectSpread({
legacyStore: args.legacyCryptoStore,
storeHandle
}, args));
}
const rustCrypto = await initOlmMachine(args, storeHandle);
storeHandle.free();
logger.debug("Completed rust crypto-sdk setup");
return rustCrypto;
}
async function initOlmMachine({
logger,
http,
userId,
deviceId,
secretStorage,
cryptoCallbacks,
legacyCryptoStore,
enableEncryptedStateEvents,
caCertsPem
}, storeHandle) {
logger.debug("Init OlmMachine");
const olmMachine = await RustSdkCryptoJs.OlmMachine.initFromStore(new RustSdkCryptoJs.UserId(userId), new RustSdkCryptoJs.DeviceId(deviceId), storeHandle, logger, caCertsPem);
// A final migration step, now that we have an OlmMachine.
if (legacyCryptoStore) {
await migrateRoomSettingsFromLegacyCrypto({
logger,
legacyStore: legacyCryptoStore,
olmMachine
});
}
// enable tracing in the rust-sdk
new RustSdkCryptoJs.Tracing(RustSdkCryptoJs.LoggerLevel.Trace).turnOn();
const u = new RustSdkCryptoJs.UserId(userId);
const d = new RustSdkCryptoJs.DeviceId(deviceId);
_logger.logger.info("Init OlmMachine");
// Disable room key requests, per https://github.com/vector-im/element-web/issues/26524.
olmMachine.roomKeyRequestsEnabled = false;
const rustCrypto = new RustCrypto(logger, olmMachine, http, userId, deviceId, secretStorage, cryptoCallbacks, enableEncryptedStateEvents);
olmMachine.registerRoomKeyUpdatedCallback(sessions => rustCrypto.onRoomKeysUpdated(sessions));
olmMachine.registerRoomKeysWithheldCallback(withheld => rustCrypto.onRoomKeysWithheld(withheld));
olmMachine.registerUserIdentityUpdatedCallback(userId => rustCrypto.onUserIdentityUpdated(userId));
olmMachine.registerDevicesUpdatedCallback(userIds => rustCrypto.onDevicesUpdated(userIds));
// Check if there are any key backup secrets pending processing. There may be multiple secrets to process if several devices have gossiped them.
// The `registerReceiveSecretCallback` function will only be triggered for new secrets. If the client is restarted before processing them, the secrets will need to be manually handled.
void rustCrypto.checkSecrets("m.megolm_backup.v1");
// Register a callback to be notified when a new secret is received, as for now only the key backup secret is supported (the cross signing secrets are handled automatically by the OlmMachine)
olmMachine.registerReceiveSecretCallback((name, _value) =>
// Instead of directly checking the secret value, we poll the inbox to get all values for that secret type.
// Once we have all the values, we can safely clear the secret inbox.
rustCrypto.checkSecrets(name));
// TODO: use the pickle key for the passphrase
const olmMachine = await RustSdkCryptoJs.OlmMachine.initialize(u, d, storePrefix !== null && storePrefix !== void 0 ? storePrefix : undefined, (_ref = storePrefix && "test pass") !== null && _ref !== void 0 ? _ref : undefined);
const rustCrypto = new _rustCrypto.RustCrypto(olmMachine, http, userId, deviceId, secretStorage, cryptoCallbacks);
await olmMachine.registerRoomKeyUpdatedCallback(sessions => rustCrypto.onRoomKeysUpdated(sessions));
// Tell the OlmMachine to think about its outgoing requests before we hand control back to the application.
//
@@ -115,49 +65,7 @@ async function initOlmMachine({
//
// XXX: find a less hacky way to do this.
await olmMachine.outgoingRequests();
if (legacyCryptoStore && (await legacyCryptoStore.containsData())) {
const migrationState = await legacyCryptoStore.getMigrationState();
if (migrationState < MigrationState.INITIAL_OWN_KEY_QUERY_DONE) {
logger.debug(`Performing initial key query after migration`);
// We need to do an initial keys query so that the rust stack can properly update trust of
// the user device and identity from the migrated private keys.
// If not done, there is a short period where the own device/identity trust will be undefined after migration.
let initialKeyQueryDone = false;
while (!initialKeyQueryDone) {
try {
await rustCrypto.userHasCrossSigningKeys(userId);
initialKeyQueryDone = true;
} catch (e) {
// If the initial key query fails, we retry until it succeeds.
logger.error("Failed to check for cross-signing keys after migration, retrying", e);
}
}
// If the private master cross-signing key was not cached in the legacy store, the rust session
// will not be able to establish the trust of the user identity.
// That means that after migration the session could revert to unverified.
// In order to avoid asking the users to re-verify their sessions, we need to migrate the legacy local trust
// (if the legacy session was already verified) to the new session.
await migrateLegacyLocalTrustIfNeeded({
legacyCryptoStore,
rustCrypto,
logger
});
await legacyCryptoStore.setMigrationState(MigrationState.INITIAL_OWN_KEY_QUERY_DONE);
}
}
// If we have any recently-joined rooms, see if we have a pending key bundle for them.
for (const pendingDetails of await olmMachine.getAllRoomsPendingKeyBundles()) {
const roomId = pendingDetails.roomId.toString();
if (Date.now() - pendingDetails.inviteAcceptedAtMillis <= MAX_INVITE_ACCEPTANCE_MS_FOR_KEY_BUNDLE) {
logger.info(`Checking for pending key bundle for recently-joined room ${roomId} (joined ${new Date(pendingDetails.inviteAcceptedAtMillis).toISOString()})`);
await rustCrypto.maybeAcceptKeyBundle(roomId, pendingDetails.inviterId.toString());
} else {
logger.info(`Clearing pending-key-bundle flag for room ${roomId} (too old: joined ${new Date(pendingDetails.inviteAcceptedAtMillis).toISOString()})`);
await olmMachine.clearRoomPendingKeyBundle(new RustSdkCryptoJs.RoomId(roomId));
}
}
_logger.logger.info("Completed rust crypto-sdk setup");
return rustCrypto;
}
//# sourceMappingURL=index.js.map