Convert IdentityAuthClient to TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-09-27 09:54:55 +02:00
parent 84c665ec2b
commit 1fe96cae8a
No known key found for this signature in database
GPG key ID: 55C211A1226CB17D

View file

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React from "react";
import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types'; import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types';
import { createClient } from 'matrix-js-sdk/src/matrix'; import { createClient, MatrixClient } from 'matrix-js-sdk/src/matrix';
import { MatrixClientPeg } from './MatrixClientPeg'; import { MatrixClientPeg } from './MatrixClientPeg';
import Modal from './Modal'; import Modal from './Modal';
import * as sdk from './index';
import { _t } from './languageHandler'; import { _t } from './languageHandler';
import { Service, startTermsFlow, TermsNotSignedError } from './Terms'; import { Service, startTermsFlow, TermsNotSignedError } from './Terms';
import { import {
@ -27,23 +27,25 @@ import {
doesIdentityServerHaveTerms, doesIdentityServerHaveTerms,
useDefaultIdentityServer, useDefaultIdentityServer,
} from './utils/IdentityServerUtils'; } from './utils/IdentityServerUtils';
import { abbreviateUrl } from './utils/UrlUtils';
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import QuestionDialog from "./components/views/dialogs/QuestionDialog";
import { abbreviateUrl } from "./utils/UrlUtils";
export class AbortedIdentityActionError extends Error {} export class AbortedIdentityActionError extends Error {}
export default class IdentityAuthClient { export default class IdentityAuthClient {
accessToken: string;
tempClient: MatrixClient;
authEnabled = true;
/** /**
* Creates a new identity auth client * Creates a new identity auth client
* @param {string} identityUrl The URL to contact the identity server with. * @param {string} identityUrl The URL to contact the identity server with.
* When provided, this class will operate solely within memory, refusing to * When provided, this class will operate solely within memory, refusing to
* persist any information such as tokens. Default null (not provided). * persist any information such as tokens. Default null (not provided).
*/ */
constructor(identityUrl = null) { constructor(identityUrl?: string) {
this.accessToken = null;
this.authEnabled = true;
if (identityUrl) { if (identityUrl) {
// XXX: We shouldn't have to create a whole new MatrixClient just to // XXX: We shouldn't have to create a whole new MatrixClient just to
// do identity server auth. The functions don't take an identity URL // do identity server auth. The functions don't take an identity URL
@ -54,32 +56,29 @@ export default class IdentityAuthClient {
baseUrl: "", // invalid by design baseUrl: "", // invalid by design
idBaseUrl: identityUrl, idBaseUrl: identityUrl,
}); });
} else {
// Indicates that we're using the real client, not some workaround.
this.tempClient = null;
} }
} }
get _matrixClient() { private get matrixClient(): MatrixClient {
return this.tempClient ? this.tempClient : MatrixClientPeg.get(); return this.tempClient ? this.tempClient : MatrixClientPeg.get();
} }
_writeToken() { private writeToken(): void {
if (this.tempClient) return; // temporary client: ignore if (this.tempClient) return; // temporary client: ignore
window.localStorage.setItem("mx_is_access_token", this.accessToken); window.localStorage.setItem("mx_is_access_token", this.accessToken);
} }
_readToken() { private readToken(): string {
if (this.tempClient) return null; // temporary client: ignore if (this.tempClient) return null; // temporary client: ignore
return window.localStorage.getItem("mx_is_access_token"); return window.localStorage.getItem("mx_is_access_token");
} }
hasCredentials() { public hasCredentials(): boolean {
return this.accessToken != null; // undef or null return Boolean(this.accessToken);
} }
// Returns a promise that resolves to the access_token string from the IS // Returns a promise that resolves to the access_token string from the IS
async getAccessToken({ check = true } = {}) { public async getAccessToken({ check = true } = {}): Promise<string> {
if (!this.authEnabled) { if (!this.authEnabled) {
// The current IS doesn't support authentication // The current IS doesn't support authentication
return null; return null;
@ -87,21 +86,21 @@ export default class IdentityAuthClient {
let token = this.accessToken; let token = this.accessToken;
if (!token) { if (!token) {
token = this._readToken(); token = this.readToken();
} }
if (!token) { if (!token) {
token = await this.registerForToken(check); token = await this.registerForToken(check);
if (token) { if (token) {
this.accessToken = token; this.accessToken = token;
this._writeToken(); this.writeToken();
} }
return token; return token;
} }
if (check) { if (check) {
try { try {
await this._checkToken(token); await this.checkToken(token);
} catch (e) { } catch (e) {
if ( if (
e instanceof TermsNotSignedError || e instanceof TermsNotSignedError ||
@ -114,7 +113,7 @@ export default class IdentityAuthClient {
token = await this.registerForToken(); token = await this.registerForToken();
if (token) { if (token) {
this.accessToken = token; this.accessToken = token;
this._writeToken(); this.writeToken();
} }
} }
} }
@ -122,11 +121,11 @@ export default class IdentityAuthClient {
return token; return token;
} }
async _checkToken(token) { private async checkToken(token: string): Promise<void> {
const identityServerUrl = this._matrixClient.getIdentityServerUrl(); const identityServerUrl = this.matrixClient.getIdentityServerUrl();
try { try {
await this._matrixClient.getIdentityAccount(token); await this.matrixClient.getIdentityAccount(token);
} catch (e) { } catch (e) {
if (e.errcode === "M_TERMS_NOT_SIGNED") { if (e.errcode === "M_TERMS_NOT_SIGNED") {
logger.log("Identity server requires new terms to be agreed to"); logger.log("Identity server requires new terms to be agreed to");
@ -145,8 +144,8 @@ export default class IdentityAuthClient {
!doesAccountDataHaveIdentityServer() && !doesAccountDataHaveIdentityServer() &&
!(await doesIdentityServerHaveTerms(identityServerUrl)) !(await doesIdentityServerHaveTerms(identityServerUrl))
) { ) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const { finished } = Modal.createTrackedDialog(
const { finished } = Modal.createTrackedDialog('Default identity server terms warning', '', 'Default identity server terms warning', '',
QuestionDialog, { QuestionDialog, {
title: _t("Identity server has no terms of service"), title: _t("Identity server has no terms of service"),
description: ( description: (
@ -184,13 +183,13 @@ export default class IdentityAuthClient {
// See also https://github.com/vector-im/element-web/issues/10455. // See also https://github.com/vector-im/element-web/issues/10455.
} }
async registerForToken(check=true) { public async registerForToken(check = true): Promise<string> {
const hsOpenIdToken = await MatrixClientPeg.get().getOpenIdToken(); const hsOpenIdToken = await MatrixClientPeg.get().getOpenIdToken();
// XXX: The spec is `token`, but we used `access_token` for a Sydent release. // XXX: The spec is `token`, but we used `access_token` for a Sydent release.
const { access_token: accessToken, token } = const { access_token: accessToken, token } =
await this._matrixClient.registerWithIdentityServer(hsOpenIdToken); await this.matrixClient.registerWithIdentityServer(hsOpenIdToken);
const identityAccessToken = token ? token : accessToken; const identityAccessToken = token ? token : accessToken;
if (check) await this._checkToken(identityAccessToken); if (check) await this.checkToken(identityAccessToken);
return identityAccessToken; return identityAccessToken;
} }
} }