From caadc6f95b357ef5ec203f09e89b4190dd9a45c6 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Thu, 22 Sep 2022 16:36:37 +0100 Subject: [PATCH] Implementation of MSC3882 login token request (#2687) --- spec/integ/matrix-client-methods.spec.js | 23 +++++++++++++++++++ src/@types/auth.ts | 16 +++++++++++++ src/@types/uia.ts | 29 ++++++++++++++++++++++++ src/client.ts | 24 +++++++++++++++++++- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/@types/uia.ts diff --git a/spec/integ/matrix-client-methods.spec.js b/spec/integ/matrix-client-methods.spec.js index 85b18f93e..69bfa89ca 100644 --- a/spec/integ/matrix-client-methods.spec.js +++ b/spec/integ/matrix-client-methods.spec.js @@ -1075,6 +1075,29 @@ describe("MatrixClient", function() { expect(await prom).toStrictEqual(response); }); }); + + describe("requestLoginToken", () => { + it("should hit the expected API endpoint with UIA", async () => { + const response = {}; + const uiaData = { foo: "baa" }; + const prom = client.requestLoginToken(uiaData); + httpBackend + .when("POST", "/unstable/org.matrix.msc3882/login/token", { auth: uiaData }) + .respond(200, response); + await httpBackend.flush(); + expect(await prom).toStrictEqual(response); + }); + + it("should hit the expected API endpoint without UIA", async () => { + const response = {}; + const prom = client.requestLoginToken(); + httpBackend + .when("POST", "/unstable/org.matrix.msc3882/login/token", {}) + .respond(200, response); + await httpBackend.flush(); + expect(await prom).toStrictEqual(response); + }); + }); }); function withThreadId(event, newThreadId) { diff --git a/src/@types/auth.ts b/src/@types/auth.ts index e98f6361e..36c0e2d4d 100644 --- a/src/@types/auth.ts +++ b/src/@types/auth.ts @@ -90,3 +90,19 @@ export enum SSOAction { /** The user intends to register for a new account */ REGISTER = "register", } + +/** + * The result of a successful [MSC3882](https://github.com/matrix-org/matrix-spec-proposals/pull/3882) + * `m.login.token` issuance request. + * Note that this is UNSTABLE and subject to breaking changes without notice. + */ +export interface LoginTokenPostResponse { + /** + * The token to use with `m.login.token` to authenticate. + */ + login_token: string; + /** + * Expiration in seconds. + */ + expires_in: number; +} diff --git a/src/@types/uia.ts b/src/@types/uia.ts new file mode 100644 index 000000000..079306135 --- /dev/null +++ b/src/@types/uia.ts @@ -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. +*/ + +import { IAuthData } from ".."; + +/** + * Helper type to represent HTTP request body for a UIA enabled endpoint + */ +export type UIARequest = T & { + auth?: IAuthData; +}; + +/** + * Helper type to represent HTTP response body for a UIA enabled endpoint + */ +export type UIAResponse = T | IAuthData; diff --git a/src/client.ts b/src/client.ts index f9e9df1d6..f1dd37f3d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -189,7 +189,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 { ILoginFlowsResponse, IRefreshTokenResponse, SSOAction } from "./@types/auth"; +import { LoginTokenPostResponse, ILoginFlowsResponse, IRefreshTokenResponse, SSOAction } from "./@types/auth"; import { TypedEventEmitter } from "./models/typed-event-emitter"; import { ReceiptType } from "./@types/read_receipts"; import { MSC3575SlidingSyncRequest, MSC3575SlidingSyncResponse, SlidingSync } from "./sliding-sync"; @@ -201,6 +201,7 @@ import { ToDeviceMessageQueue } from "./ToDeviceMessageQueue"; import { ToDeviceBatch } from "./models/ToDeviceMessage"; import { MAIN_ROOM_TIMELINE } from "./models/read-receipt"; import { IgnoredInvites } from "./models/invites-ignorer"; +import { UIARequest, UIAResponse } from "./@types/uia"; export type Store = IStore; @@ -7291,6 +7292,27 @@ export class MatrixClient extends TypedEventEmitter>} Resolves: On success, the token response + * or UIA auth data. + */ + public requestLoginToken(auth?: IAuthData): Promise> { + const body: UIARequest<{}> = { auth }; + return this.http.authedRequest( + undefined, // no callback support + Method.Post, + "/org.matrix.msc3882/login/token", + undefined, // no query params + body, + { prefix: PREFIX_UNSTABLE }, + ); + } + /** * Get the fallback URL to use for unknown interactive-auth stages. *