mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 19:45:05 +01:00
WIP2
This commit is contained in:
parent
faf4ea6434
commit
718b410253
@ -24,6 +24,7 @@ import { ObservableMap } from "../observable/index.js";
|
|||||||
import {User} from "./User.js";
|
import {User} from "./User.js";
|
||||||
import {DeviceMessageHandler} from "./DeviceMessageHandler.js";
|
import {DeviceMessageHandler} from "./DeviceMessageHandler.js";
|
||||||
import {Account as E2EEAccount} from "./e2ee/Account.js";
|
import {Account as E2EEAccount} from "./e2ee/Account.js";
|
||||||
|
import {uploadAccountAsDehydratedDevice} from "./e2ee/Dehydration.js";
|
||||||
import {Decryption as OlmDecryption} from "./e2ee/olm/Decryption.js";
|
import {Decryption as OlmDecryption} from "./e2ee/olm/Decryption.js";
|
||||||
import {Encryption as OlmEncryption} from "./e2ee/olm/Encryption.js";
|
import {Encryption as OlmEncryption} from "./e2ee/olm/Encryption.js";
|
||||||
import {Decryption as MegOlmDecryption} from "./e2ee/megolm/Decryption";
|
import {Decryption as MegOlmDecryption} from "./e2ee/megolm/Decryption";
|
||||||
@ -284,8 +285,8 @@ export class Session {
|
|||||||
pickleKey: PICKLE_KEY,
|
pickleKey: PICKLE_KEY,
|
||||||
userId: this._sessionInfo.userId,
|
userId: this._sessionInfo.userId,
|
||||||
olmWorker: this._olmWorker,
|
olmWorker: this._olmWorker,
|
||||||
deviceId,
|
deviceId: this.deviceId,
|
||||||
storage,
|
storage: this._storage,
|
||||||
});
|
});
|
||||||
log.set("keys", this._e2eeAccount.identityKeys);
|
log.set("keys", this._e2eeAccount.identityKeys);
|
||||||
this._setupEncryption();
|
this._setupEncryption();
|
||||||
|
@ -29,6 +29,7 @@ import {Session} from "./Session.js";
|
|||||||
import {PasswordLoginMethod} from "./login/PasswordLoginMethod.js";
|
import {PasswordLoginMethod} from "./login/PasswordLoginMethod.js";
|
||||||
import {TokenLoginMethod} from "./login/TokenLoginMethod.js";
|
import {TokenLoginMethod} from "./login/TokenLoginMethod.js";
|
||||||
import {SSOLoginHelper} from "./login/SSOLoginHelper.js";
|
import {SSOLoginHelper} from "./login/SSOLoginHelper.js";
|
||||||
|
import {getDehydratedDevice} from "./e2ee/Dehydration.js";
|
||||||
|
|
||||||
export const LoadStatus = createEnum(
|
export const LoadStatus = createEnum(
|
||||||
"NotLoading",
|
"NotLoading",
|
||||||
@ -38,7 +39,7 @@ export const LoadStatus = createEnum(
|
|||||||
"SetupAccount", // asked to restore from dehydrated device if present, call sc.accountSetup.finish() to progress to the next stage
|
"SetupAccount", // asked to restore from dehydrated device if present, call sc.accountSetup.finish() to progress to the next stage
|
||||||
"Loading",
|
"Loading",
|
||||||
"SessionSetup", // upload e2ee keys, ...
|
"SessionSetup", // upload e2ee keys, ...
|
||||||
"Migrating", //not used atm, but would fit here
|
"Migrating", // not used atm, but would fit here
|
||||||
"FirstSync",
|
"FirstSync",
|
||||||
"Error",
|
"Error",
|
||||||
"Ready",
|
"Ready",
|
||||||
@ -174,7 +175,7 @@ export class SessionContainer {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dehydratedDevice = await this._inspectAccountAfterLogin(sessionInfo);
|
const dehydratedDevice = await this._inspectAccountAfterLogin(sessionInfo, log);
|
||||||
if (dehydratedDevice) {
|
if (dehydratedDevice) {
|
||||||
sessionInfo.deviceId = dehydratedDevice.deviceId;
|
sessionInfo.deviceId = dehydratedDevice.deviceId;
|
||||||
}
|
}
|
||||||
@ -240,7 +241,7 @@ export class SessionContainer {
|
|||||||
});
|
});
|
||||||
await this._session.load(log);
|
await this._session.load(log);
|
||||||
if (dehydratedDevice) {
|
if (dehydratedDevice) {
|
||||||
await log.wrap("dehydrateIdentity", log => await this._session.dehydrateIdentity(dehydratedDevice, log));
|
await log.wrap("dehydrateIdentity", log => this._session.dehydrateIdentity(dehydratedDevice, log));
|
||||||
} else if (!this._session.hasIdentity) {
|
} else if (!this._session.hasIdentity) {
|
||||||
this._status.set(LoadStatus.SessionSetup);
|
this._status.set(LoadStatus.SessionSetup);
|
||||||
await log.wrap("createIdentity", log => this._session.createIdentity(log));
|
await log.wrap("createIdentity", log => this._session.createIdentity(log));
|
||||||
@ -308,25 +309,27 @@ export class SessionContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _inspectAccountAfterLogin(sessionInfo) {
|
_inspectAccountAfterLogin(sessionInfo, log) {
|
||||||
this._status.set(LoadStatus.QueryAccount);
|
return log.wrap("inspectAccount", async log => {
|
||||||
const hsApi = new HomeServerApi({
|
this._status.set(LoadStatus.QueryAccount);
|
||||||
homeserver: sessionInfo.homeServer,
|
const hsApi = new HomeServerApi({
|
||||||
accessToken: sessionInfo.accessToken,
|
homeserver: sessionInfo.homeServer,
|
||||||
request: this._platform.request,
|
accessToken: sessionInfo.accessToken,
|
||||||
|
request: this._platform.request,
|
||||||
|
});
|
||||||
|
const olm = await this._olmPromise;
|
||||||
|
const encryptedDehydratedDevice = await getDehydratedDevice(hsApi, olm, log);
|
||||||
|
if (encryptedDehydratedDevice) {
|
||||||
|
let resolveStageFinish;
|
||||||
|
const promiseStageFinish = new Promise(r => resolveStageFinish = r);
|
||||||
|
this._accountSetup = new AccountSetup(encryptedDehydratedDevice, resolveStageFinish);
|
||||||
|
this._status.set(LoadStatus.SetupAccount);
|
||||||
|
await promiseStageFinish;
|
||||||
|
const dehydratedDevice = this._accountSetup?._dehydratedDevice;
|
||||||
|
this._accountSetup = null;
|
||||||
|
return dehydratedDevice;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const olm = await this._olmPromise;
|
|
||||||
const encryptedDehydratedDevice = await getDehydratedDevice(hsApi, olm);
|
|
||||||
if (encryptedDehydratedDevice) {
|
|
||||||
let resolveStageFinish;
|
|
||||||
const promiseStageFinish = new Promise(r => resolveStageFinish = r);
|
|
||||||
this._accountSetup = new AccountSetup(encryptedDehydratedDevice, resolveStageFinish);
|
|
||||||
this._status.set(LoadStatus.SetupAccount);
|
|
||||||
await promiseStageFinish;
|
|
||||||
const dehydratedDevice = this._accountSetup?._dehydratedDevice;
|
|
||||||
this._accountSetup = null;
|
|
||||||
return dehydratedDevice;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get accountSetup() {
|
get accountSetup() {
|
||||||
|
@ -55,11 +55,11 @@ export class Account {
|
|||||||
|
|
||||||
static async adoptDehydratedDevice({olm, dehydratedDevice, pickleKey, hsApi, userId, olmWorker, storage}) {
|
static async adoptDehydratedDevice({olm, dehydratedDevice, pickleKey, hsApi, userId, olmWorker, storage}) {
|
||||||
const account = dehydratedDevice.adoptUnpickledOlmAccount();
|
const account = dehydratedDevice.adoptUnpickledOlmAccount();
|
||||||
const areDeviceKeysUploaded = true;
|
const oneTimeKeys = JSON.parse(account.one_time_keys());
|
||||||
const oneTimeKeys = JSON.parse(this._account.one_time_keys());
|
|
||||||
// only one algorithm supported by olm atm, so hardcode its name
|
// only one algorithm supported by olm atm, so hardcode its name
|
||||||
const oneTimeKeysEntries = Object.entries(oneTimeKeys.curve25519);
|
const oneTimeKeysEntries = Object.entries(oneTimeKeys.curve25519);
|
||||||
const serverOTKCount = oneTimeKeysEntries.length;
|
const serverOTKCount = oneTimeKeysEntries.length;
|
||||||
|
const areDeviceKeysUploaded = true;
|
||||||
await initiallyStoreAccount(account, pickleKey, areDeviceKeysUploaded, serverOTKCount, storage);
|
await initiallyStoreAccount(account, pickleKey, areDeviceKeysUploaded, serverOTKCount, storage);
|
||||||
return new Account({
|
return new Account({
|
||||||
pickleKey, hsApi, account, userId,
|
pickleKey, hsApi, account, userId,
|
||||||
@ -76,11 +76,13 @@ export class Account {
|
|||||||
account.create();
|
account.create();
|
||||||
account.generate_one_time_keys(account.max_number_of_one_time_keys());
|
account.generate_one_time_keys(account.max_number_of_one_time_keys());
|
||||||
}
|
}
|
||||||
|
const areDeviceKeysUploaded = false;
|
||||||
|
const serverOTKCount = 0;
|
||||||
if (storage) {
|
if (storage) {
|
||||||
await initiallyStoreAccount(account, pickleKey, false, 0, storage);
|
await initiallyStoreAccount(account, pickleKey, areDeviceKeysUploaded, serverOTKCount, storage);
|
||||||
}
|
}
|
||||||
return new Account({pickleKey, hsApi, account, userId,
|
return new Account({pickleKey, hsApi, account, userId,
|
||||||
deviceId, areDeviceKeysUploaded, serverOTKCount: 0, olm, olmWorker});
|
deviceId, areDeviceKeysUploaded, serverOTKCount, olm, olmWorker});
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor({pickleKey, hsApi, account, userId, deviceId, areDeviceKeysUploaded, serverOTKCount, olm, olmWorker}) {
|
constructor({pickleKey, hsApi, account, userId, deviceId, areDeviceKeysUploaded, serverOTKCount, olm, olmWorker}) {
|
||||||
|
@ -14,20 +14,23 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const DEHYDRATION_LIBOLM_PICKLE_ALGORITHM = "org.matrix.msc2697.v1.olm.libolm_pickle";
|
const DEHYDRATION_LIBOLM_PICKLE_ALGORITHM = "org.matrix.msc2697.v1.olm.libolm_pickle";
|
||||||
|
|
||||||
async function getDehydratedDevice(hsApi, olm) {
|
export async function getDehydratedDevice(hsApi, olm, log) {
|
||||||
const response = await hsApi.getDehydratedDevice().response();
|
try {
|
||||||
if (response.device_data.algorithm === DEHYDRATION_LIBOLM_PICKLE_ALGORITHM) {
|
const response = await hsApi.getDehydratedDevice({log}).response();
|
||||||
return new DehydratedDevice(response, olm);
|
if (response.device_data.algorithm === DEHYDRATION_LIBOLM_PICKLE_ALGORITHM) {
|
||||||
|
return new EncryptedDehydratedDevice(response, olm);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.name !== "HomeServerError") {
|
||||||
|
log.error = err;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function hasRemainingDevice(ownUserId, ownDeviceId, storage) {
|
export async function uploadAccountAsDehydratedDevice(account, hsApi, key, deviceDisplayName, log) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function uploadAccountAsDehydratedDevice(account, hsApi, key, deviceDisplayName, log) {
|
|
||||||
const response = await hsApi.createDehydratedDevice({
|
const response = await hsApi.createDehydratedDevice({
|
||||||
device_data: {
|
device_data: {
|
||||||
algorithm: DEHYDRATION_LIBOLM_PICKLE_ALGORITHM,
|
algorithm: DEHYDRATION_LIBOLM_PICKLE_ALGORITHM,
|
||||||
@ -66,7 +69,7 @@ class DehydratedDevice {
|
|||||||
this._account = account;
|
this._account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
claim(hsApi, log) {
|
async claim(hsApi, log) {
|
||||||
try {
|
try {
|
||||||
const response = await hsApi.claimDehydratedDevice(this.deviceId, {log}).response();
|
const response = await hsApi.claimDehydratedDevice(this.deviceId, {log}).response();
|
||||||
return response.success;
|
return response.success;
|
||||||
@ -83,6 +86,6 @@ class DehydratedDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get deviceId() {
|
get deviceId() {
|
||||||
this._dehydratedDevice.device_id;
|
return this._dehydratedDevice.device_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,12 +242,12 @@ export class HomeServerApi {
|
|||||||
return this._get(`/dehydrated_device`, null, null, options);
|
return this._get(`/dehydrated_device`, null, null, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
createDehydratedDevice(payload, options = null) {
|
createDehydratedDevice(payload, options = {}) {
|
||||||
options.prefix = DEHYDRATION_PREFIX;
|
options.prefix = DEHYDRATION_PREFIX;
|
||||||
return this._put(`/dehydrated_device`, null, payload, options);
|
return this._put(`/dehydrated_device`, null, payload, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
claimDehydratedDevice(deviceId) {
|
claimDehydratedDevice(deviceId, options = {}) {
|
||||||
options.prefix = DEHYDRATION_PREFIX;
|
options.prefix = DEHYDRATION_PREFIX;
|
||||||
return this._post(`/dehydrated_device/claim`, null, {device_id: deviceId}, options);
|
return this._post(`/dehydrated_device/claim`, null, {device_id: deviceId}, options);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user