You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Add functions to support refresh tokens (#2178)
* Add functions for refreshing access tokens * Add function to change the client's access token in flight * Appease the linter * Use sensible code style
This commit is contained in:
29
src/@types/auth.ts
Normal file
29
src/@types/auth.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// disable lint because these are wire responses
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
/**
|
||||
* Represents a response to the CSAPI `/refresh` endpoint.
|
||||
*/
|
||||
export interface IRefreshTokenResponse {
|
||||
access_token: string;
|
||||
expires_in_ms: number;
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
/* eslint-enable camelcase */
|
||||
@@ -20,7 +20,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { EventEmitter } from "events";
|
||||
import { EmoteEvent, MessageEvent, NoticeEvent, IPartialEvent } from "matrix-events-sdk";
|
||||
import { EmoteEvent, IPartialEvent, MessageEvent, NoticeEvent } from "matrix-events-sdk";
|
||||
|
||||
import { ISyncStateData, SyncApi, SyncState } from "./sync";
|
||||
import { EventStatus, IContent, IDecryptOptions, IEvent, MatrixEvent } from "./models/event";
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
PREFIX_MEDIA_R0,
|
||||
PREFIX_R0,
|
||||
PREFIX_UNSTABLE,
|
||||
PREFIX_V1,
|
||||
retryNetworkOperation,
|
||||
UploadContentResponseType,
|
||||
} from "./http-api";
|
||||
@@ -87,14 +88,7 @@ import {
|
||||
} from "./crypto/keybackup";
|
||||
import { IIdentityServerProvider } from "./@types/IIdentityServerProvider";
|
||||
import { MatrixScheduler } from "./scheduler";
|
||||
import {
|
||||
IAuthData,
|
||||
ICryptoCallbacks,
|
||||
IMinimalEvent,
|
||||
IRoomEvent,
|
||||
IStateEvent,
|
||||
NotificationCountType,
|
||||
} from "./matrix";
|
||||
import { IAuthData, ICryptoCallbacks, IMinimalEvent, IRoomEvent, IStateEvent, NotificationCountType } from "./matrix";
|
||||
import {
|
||||
CrossSigningKey,
|
||||
IAddSecretStorageKeyOpts,
|
||||
@@ -160,6 +154,7 @@ import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, Rule
|
||||
import { IThreepid } from "./@types/threepids";
|
||||
import { CryptoStore } from "./crypto/store/base";
|
||||
import { MediaHandler } from "./webrtc/mediaHandler";
|
||||
import { IRefreshTokenResponse } from "./@types/auth";
|
||||
|
||||
export type Store = IStore;
|
||||
export type SessionStore = WebStorageSessionStore;
|
||||
@@ -6619,6 +6614,14 @@ export class MatrixClient extends EventEmitter {
|
||||
return this.http.opts.accessToken || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the access token associated with this account.
|
||||
* @param {string} token The new access token.
|
||||
*/
|
||||
public setAccessToken(token: string) {
|
||||
this.http.opts.accessToken = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} true if there is a valid access_token for this client.
|
||||
*/
|
||||
@@ -6695,6 +6698,7 @@ export class MatrixClient extends EventEmitter {
|
||||
|
||||
const params: any = {
|
||||
auth: auth,
|
||||
refresh_token: true, // always ask for a refresh token - does nothing if unsupported
|
||||
};
|
||||
if (username !== undefined && username !== null) {
|
||||
params.username = username;
|
||||
@@ -6772,6 +6776,31 @@ export class MatrixClient extends EventEmitter {
|
||||
return this.http.request(callback, Method.Post, "/register", params, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes an access token using a provided refresh token. The refresh token
|
||||
* must be valid for the current access token known to the client instance.
|
||||
*
|
||||
* Note that this function will not cause a logout if the token is deemed
|
||||
* unknown by the server - the caller is responsible for managing logout
|
||||
* actions on error.
|
||||
* @param {string} refreshToken The refresh token.
|
||||
* @return {Promise<IRefreshTokenResponse>} Resolves to the new token.
|
||||
* @return {module:http-api.MatrixError} Rejects with an error response.
|
||||
*/
|
||||
public refreshToken(refreshToken: string): Promise<IRefreshTokenResponse> {
|
||||
return this.http.authedRequest(
|
||||
undefined,
|
||||
Method.Post,
|
||||
"/refresh",
|
||||
undefined,
|
||||
{ refresh_token: refreshToken },
|
||||
{
|
||||
prefix: PREFIX_V1,
|
||||
inhibitLogoutEmit: true, // we don't want to cause logout loops
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:client.callback} callback Optional.
|
||||
* @return {Promise} Resolves: TODO
|
||||
|
||||
@@ -111,6 +111,12 @@ interface IRequestOpts<T> {
|
||||
json?: boolean; // defaults to true
|
||||
qsStringifyOptions?: CoreOptions["qsStringifyOptions"];
|
||||
bodyParser?(body: string): T;
|
||||
|
||||
// Set to true to prevent the request function from emitting
|
||||
// a Session.logged_out event. This is intended for use on
|
||||
// endpoints where M_UNKNOWN_TOKEN is a valid/notable error
|
||||
// response, such as with token refreshes.
|
||||
inhibitLogoutEmit?: boolean;
|
||||
}
|
||||
|
||||
export interface IUpload {
|
||||
@@ -596,7 +602,7 @@ export class MatrixHttpApi {
|
||||
const requestPromise = this.request<T, O>(callback, method, path, queryParams, data, requestOpts);
|
||||
|
||||
requestPromise.catch((err: MatrixError) => {
|
||||
if (err.errcode == 'M_UNKNOWN_TOKEN') {
|
||||
if (err.errcode == 'M_UNKNOWN_TOKEN' && !requestOpts?.inhibitLogoutEmit) {
|
||||
this.eventEmitter.emit("Session.logged_out", err);
|
||||
} else if (err.errcode == 'M_CONSENT_NOT_GIVEN') {
|
||||
this.eventEmitter.emit(
|
||||
|
||||
Reference in New Issue
Block a user