UNPKG

@vector-im/matrix-bot-sdk

Version:

TypeScript/JavaScript SDK for Matrix bots and appservices

126 lines 5.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MatrixAuth = void 0; const MatrixClient_1 = require("./MatrixClient"); /** * Functions for interacting with Matrix prior to having an access token. Intended * to be used for logging in/registering to get a MatrixClient instance. * * By design, this limits the options used to create the MatrixClient. To specify * custom elements to the client, get the access token from the returned client * and create a new MatrixClient instance. Due to the nature of Matrix, it is * also recommended to use the homeserverUrl from the generated MatrixClient as * it may be different from that given to the MatrixAuth class. */ class MatrixAuth { homeserverUrl; /** * Creates a new MatrixAuth class for creating a MatrixClient * @param {string} homeserverUrl The homeserver URL to authenticate against. */ constructor(homeserverUrl) { this.homeserverUrl = homeserverUrl; // nothing to do } /** * Generate a client with no access token so we can reuse the doRequest * logic already written. */ createTemplateClient() { return new MatrixClient_1.MatrixClient(this.homeserverUrl, ""); } /** * Performs simple registration using a password for the account. This will * assume the server supports the m.login.password flow for registration, and * will attempt to complete only that stage. The caller is expected to determine * if the homeserver supports registration prior to invocation. * @param {string} localpart The localpart (username) to register * @param {string} password The password to register with * @param {string} deviceName The name of the newly created device. Optional. * @returns {Promise<MatrixClient>} Resolves to a logged-in MatrixClient */ async passwordRegister(localpart, password, deviceName) { // First try and complete the stage without UIA in hopes the server is kind to us: const body = { username: localpart, password: password, initial_device_display_name: deviceName, }; let response; try { response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/register", null, body); } catch (e) { if (e.statusCode === 401) { if (typeof (e.body) === "string") e.body = JSON.parse(e.body); if (!e.body) throw new Error(JSON.stringify(Object.keys(e))); // 401 means we need to do UIA, so try and complete a stage const sessionId = e.body['session']; const expectedFlow = ["m.login.dummy"]; let hasFlow = false; for (const flow of e.body['flows']) { const stages = flow['stages']; if (stages.length !== expectedFlow.length) continue; let stagesMatch = true; for (let i = 0; i < stages.length; i++) { if (stages[i] !== expectedFlow[i]) { stagesMatch = false; break; } } if (stagesMatch) { hasFlow = true; break; } } if (!hasFlow) throw new Error("Failed to find appropriate login flow in User-Interactive Authentication"); body['auth'] = { type: expectedFlow[0], session: sessionId, }; response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/register", null, body); } } if (!response) throw new Error("Failed to register"); const accessToken = response['access_token']; if (!accessToken) throw new Error("No access token returned"); return new MatrixClient_1.MatrixClient(this.homeserverUrl, accessToken); } /** * Performs simple password login with the homeserver. The caller is * expected to confirm if the homeserver supports this login flow prior * to invocation. * @param {string} username The username (localpart or user ID) to log in with * @param {string} password The password for the account * @param {string} deviceName The name of the newly created device. Optional. * @returns {Promise<MatrixClient>} Resolves to a logged-in MatrixClient */ async passwordLogin(username, password, deviceName) { const body = { type: "m.login.password", identifier: { type: "m.id.user", user: username, }, password: password, initial_device_display_name: deviceName, }; const response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/login", null, body); const accessToken = response["access_token"]; if (!accessToken) throw new Error("Expected access token in response - got nothing"); let homeserverUrl = this.homeserverUrl; if (response['well_known'] && response['well_known']['m.homeserver'] && response['well_known']['m.homeserver']['base_url']) { homeserverUrl = response['well_known']['m.homeserver']['base_url']; } return new MatrixClient_1.MatrixClient(homeserverUrl, accessToken); } } exports.MatrixAuth = MatrixAuth; //# sourceMappingURL=MatrixAuth.js.map