mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-22 19:14:52 +01:00
Merge pull request #889 from vector-im/login_with_access_token
Add abiity to setup session immediately after registration without using /login
This commit is contained in:
commit
4d5f202d94
@ -137,7 +137,7 @@ export class Client {
|
||||
async startRegistration(homeserver, username, password, initialDeviceDisplayName, flowSelector) {
|
||||
const request = this._platform.request;
|
||||
const hsApi = new HomeServerApi({homeserver, request});
|
||||
const registration = new Registration(hsApi, {
|
||||
const registration = new Registration(homeserver, hsApi, {
|
||||
username,
|
||||
password,
|
||||
initialDeviceDisplayName,
|
||||
@ -146,6 +146,16 @@ export class Client {
|
||||
return registration;
|
||||
}
|
||||
|
||||
/** Method to start client after registration or with given access token.
|
||||
* To start the client after registering, use `startWithAuthData(registration.authData)`.
|
||||
* `homeserver` won't be resolved or normalized using this method,
|
||||
* use `lookupHomeserver` first if needed (not needed after registration) */
|
||||
async startWithAuthData({accessToken, deviceId, userId, homeserver}) {
|
||||
this._platform.logger.run("startWithAuthData", async (log) => {
|
||||
await this._createSessionAfterAuth({accessToken, deviceId, userId, homeserver}, true, log);
|
||||
});
|
||||
}
|
||||
|
||||
async startWithLogin(loginMethod, {inspectAccountSetup} = {}) {
|
||||
const currentStatus = this._status.get();
|
||||
if (currentStatus !== LoadStatus.LoginFailed &&
|
||||
@ -156,23 +166,17 @@ export class Client {
|
||||
this._resetStatus();
|
||||
await this._platform.logger.run("login", async log => {
|
||||
this._status.set(LoadStatus.Login);
|
||||
const clock = this._platform.clock;
|
||||
let sessionInfo;
|
||||
try {
|
||||
const request = this._platform.request;
|
||||
const hsApi = new HomeServerApi({homeserver: loginMethod.homeserver, request});
|
||||
const loginData = await loginMethod.login(hsApi, "Hydrogen", log);
|
||||
const sessionId = this.createNewSessionId();
|
||||
sessionInfo = {
|
||||
id: sessionId,
|
||||
deviceId: loginData.device_id,
|
||||
userId: loginData.user_id,
|
||||
homeServer: loginMethod.homeserver, // deprecate this over time
|
||||
homeserver: loginMethod.homeserver,
|
||||
accessToken: loginData.access_token,
|
||||
lastUsed: clock.now()
|
||||
};
|
||||
log.set("id", sessionId);
|
||||
} catch (err) {
|
||||
this._error = err;
|
||||
if (err.name === "HomeServerError") {
|
||||
@ -191,30 +195,45 @@ export class Client {
|
||||
}
|
||||
return;
|
||||
}
|
||||
let dehydratedDevice;
|
||||
if (inspectAccountSetup) {
|
||||
dehydratedDevice = await this._inspectAccountAfterLogin(sessionInfo, log);
|
||||
if (dehydratedDevice) {
|
||||
sessionInfo.deviceId = dehydratedDevice.deviceId;
|
||||
}
|
||||
}
|
||||
await this._platform.sessionInfoStorage.add(sessionInfo);
|
||||
// loading the session can only lead to
|
||||
// LoadStatus.Error in case of an error,
|
||||
// so separate try/catch
|
||||
try {
|
||||
await this._loadSessionInfo(sessionInfo, dehydratedDevice, log);
|
||||
log.set("status", this._status.get());
|
||||
} catch (err) {
|
||||
log.catch(err);
|
||||
// free olm Account that might be contained
|
||||
dehydratedDevice?.dispose();
|
||||
this._error = err;
|
||||
this._status.set(LoadStatus.Error);
|
||||
}
|
||||
await this._createSessionAfterAuth(sessionInfo, inspectAccountSetup, log);
|
||||
});
|
||||
}
|
||||
|
||||
async _createSessionAfterAuth({deviceId, userId, accessToken, homeserver}, inspectAccountSetup, log) {
|
||||
const id = this.createNewSessionId();
|
||||
const lastUsed = this._platform.clock.now();
|
||||
const sessionInfo = {
|
||||
id,
|
||||
deviceId,
|
||||
userId,
|
||||
homeServer: homeserver, // deprecate this over time
|
||||
homeserver,
|
||||
accessToken,
|
||||
lastUsed,
|
||||
};
|
||||
let dehydratedDevice;
|
||||
if (inspectAccountSetup) {
|
||||
dehydratedDevice = await this._inspectAccountAfterLogin(sessionInfo, log);
|
||||
if (dehydratedDevice) {
|
||||
sessionInfo.deviceId = dehydratedDevice.deviceId;
|
||||
}
|
||||
}
|
||||
await this._platform.sessionInfoStorage.add(sessionInfo);
|
||||
// loading the session can only lead to
|
||||
// LoadStatus.Error in case of an error,
|
||||
// so separate try/catch
|
||||
try {
|
||||
await this._loadSessionInfo(sessionInfo, dehydratedDevice, log);
|
||||
log.set("status", this._status.get());
|
||||
} catch (err) {
|
||||
log.catch(err);
|
||||
// free olm Account that might be contained
|
||||
dehydratedDevice?.dispose();
|
||||
this._error = err;
|
||||
this._status.set(LoadStatus.Error);
|
||||
}
|
||||
}
|
||||
|
||||
async _loadSessionInfo(sessionInfo, dehydratedDevice, log) {
|
||||
log.set("appVersion", this._platform.version);
|
||||
const clock = this._platform.clock;
|
||||
|
@ -164,7 +164,7 @@ export class HomeServerApi {
|
||||
return this._unauthedRequest("GET", this._url("/login"));
|
||||
}
|
||||
|
||||
register(username: string | null, password: string, initialDeviceDisplayName: string, auth?: Record<string, any>, inhibitLogin: boolean = true , options: BaseRequestOptions = {}): IHomeServerRequest {
|
||||
register(username: string | null, password: string, initialDeviceDisplayName: string, auth?: Record<string, any>, inhibitLogin: boolean = false , options: BaseRequestOptions = {}): IHomeServerRequest {
|
||||
options.allowedStatusCodes = [401];
|
||||
const body: any = {
|
||||
auth,
|
||||
|
@ -25,6 +25,7 @@ import type {
|
||||
RegistrationResponseMoreDataNeeded,
|
||||
RegistrationResponse,
|
||||
RegistrationResponseSuccess,
|
||||
AuthData,
|
||||
RegistrationParams,
|
||||
} from "./types";
|
||||
|
||||
@ -34,9 +35,11 @@ export class Registration {
|
||||
private readonly _hsApi: HomeServerApi;
|
||||
private readonly _accountDetails: AccountDetails;
|
||||
private readonly _flowSelector: FlowSelector;
|
||||
private _sessionInfo?: RegistrationResponseSuccess
|
||||
private _registerResponse?: RegistrationResponseSuccess;
|
||||
public readonly homeserver: string;
|
||||
|
||||
constructor(hsApi: HomeServerApi, accountDetails: AccountDetails, flowSelector?: FlowSelector) {
|
||||
constructor(homeserver: string, hsApi: HomeServerApi, accountDetails: AccountDetails, flowSelector?: FlowSelector) {
|
||||
this.homeserver = homeserver;
|
||||
this._hsApi = hsApi;
|
||||
this._accountDetails = accountDetails;
|
||||
this._flowSelector = flowSelector ?? (flows => flows[0]);
|
||||
@ -91,7 +94,7 @@ export class Registration {
|
||||
private async parseRegistrationResponse(response: RegistrationResponse, currentStage: BaseRegistrationStage) {
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
this._sessionInfo = response;
|
||||
this._registerResponse = response;
|
||||
return undefined;
|
||||
case 401:
|
||||
if (response.completed?.includes(currentStage.type)) {
|
||||
@ -117,7 +120,14 @@ export class Registration {
|
||||
}
|
||||
}
|
||||
|
||||
get sessionInfo(): RegistrationResponseSuccess | undefined {
|
||||
return this._sessionInfo;
|
||||
get authData(): AuthData | undefined {
|
||||
if (this._registerResponse) {
|
||||
return {
|
||||
accessToken: this._registerResponse.access_token,
|
||||
homeserver: this.homeserver,
|
||||
userId: this._registerResponse.user_id,
|
||||
deviceId: this._registerResponse.device_id,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,13 @@ export type RegistrationResponseSuccess = {
|
||||
status: 200;
|
||||
}
|
||||
|
||||
export type AuthData = {
|
||||
userId: string;
|
||||
deviceId: string;
|
||||
homeserver: string;
|
||||
accessToken?: string;
|
||||
}
|
||||
|
||||
export type RegistrationFlow = {
|
||||
stages: string[];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user