Skip to content

Commit

Permalink
Deprecate MatrixClient.login and replace with loginRequest (#4632)
Browse files Browse the repository at this point in the history
`MatrixClient.login` has some very unintuitive behaviour where it
stashes the access token, but not the device id, refresh token, etc etc, which
led people to imagine that they had a functional `MatrixClient` when they
didn't. In practice, you have to create a *new* `MatrixClient` given the `LoginResponse`.

As the first step for sorting this out, this deprecates the broken method and
replaces it with one that has sensible behaviour.
  • Loading branch information
richvdh authored Jan 20, 2025
1 parent b45d51a commit ce60162
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8246,27 +8246,33 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
/**
* @returns Promise which resolves to a LoginResponse object
* @returns Rejects: with an error response.
*
* @deprecated This method has unintuitive behaviour: it updates the `MatrixClient` instance with *some* of the
* returned credentials. Instead, call {@link loginRequest} and create a new `MatrixClient` instance using the
* results. See https://github.com/matrix-org/matrix-js-sdk/issues/4502.
*/
public login(loginType: LoginRequest["type"], data: Omit<LoginRequest, "type">): Promise<LoginResponse> {
return this.http
.authedRequest<LoginResponse>(Method.Post, "/login", undefined, {
...data,
type: loginType,
})
.then((response) => {
if (response.access_token && response.user_id) {
this.http.opts.accessToken = response.access_token;
this.credentials = {
userId: response.user_id,
};
}
return response;
});
return this.loginRequest({
...data,
type: loginType,
}).then((response) => {
if (response.access_token && response.user_id) {
this.http.opts.accessToken = response.access_token;
this.credentials = {
userId: response.user_id,
};
}
return response;
});
}

/**
* @returns Promise which resolves to a LoginResponse object
* @returns Rejects: with an error response.
*
* @deprecated This method has unintuitive behaviour: it updates the `MatrixClient` instance with *some* of the
* returned credentials. Instead, call {@link loginRequest} with `data.type: "m.login.password"`, and create a new
* `MatrixClient` instance using the results. See https://github.com/matrix-org/matrix-js-sdk/issues/4502.
*/
public loginWithPassword(user: string, password: string): Promise<LoginResponse> {
return this.login("m.login.password", {
Expand Down Expand Up @@ -8311,13 +8317,31 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param token - Login token previously received from homeserver
* @returns Promise which resolves to a LoginResponse object
* @returns Rejects: with an error response.
*
* @deprecated This method has unintuitive behaviour: it updates the `MatrixClient` instance with *some* of the
* returned credentials. Instead, call {@link loginRequest} with `data.type: "m.login.token"`, and create a new
* `MatrixClient` instance using the results. See https://github.com/matrix-org/matrix-js-sdk/issues/4502.
*/
public loginWithToken(token: string): Promise<LoginResponse> {
return this.login("m.login.token", {
token: token,
});
}

/**
* Sends a `POST /login` request to the server.
*
* If successful, this will create a new device and access token for the user.
*
* @see {@link MatrixClient.loginFlows} which makes a `GET /login` request.
* @see https://spec.matrix.org/v1.13/client-server-api/#post_matrixclientv3login
*
* @param data - Credentials and other details for the login request.
*/
public async loginRequest(data: LoginRequest): Promise<LoginResponse> {
return await this.http.authedRequest<LoginResponse>(Method.Post, "/login", undefined, data);
}

/**
* Logs out the current session.
* Obviously, further calls that require authorisation should fail after this
Expand Down

0 comments on commit ce60162

Please sign in to comment.