Factor out common login code (#2307)

Removes the duplication between the various points where we send off a login
request and parse the response.
pull/21833/head
Richard van der Hoff 2018-12-05 17:39:38 +01:00 committed by GitHub
parent a3382eb655
commit c553323d5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 78 deletions

View File

@ -32,6 +32,7 @@ import Modal from './Modal';
import sdk from './index'; import sdk from './index';
import ActiveWidgetStore from './stores/ActiveWidgetStore'; import ActiveWidgetStore from './stores/ActiveWidgetStore';
import PlatformPeg from "./PlatformPeg"; import PlatformPeg from "./PlatformPeg";
import {sendLoginRequest} from "./Login";
/** /**
* Called at startup, to attempt to build a logged-in Matrix session. It tries * Called at startup, to attempt to build a logged-in Matrix session. It tries
@ -129,27 +130,17 @@ export function attemptTokenLogin(queryParams, defaultDeviceDisplayName) {
return Promise.resolve(false); return Promise.resolve(false);
} }
// create a temporary MatrixClient to do the login return sendLoginRequest(
const client = Matrix.createClient({ queryParams.homeserver,
baseUrl: queryParams.homeserver, queryParams.identityServer,
});
return client.login(
"m.login.token", { "m.login.token", {
token: queryParams.loginToken, token: queryParams.loginToken,
initial_device_display_name: defaultDeviceDisplayName, initial_device_display_name: defaultDeviceDisplayName,
}, },
).then(function(data) { ).then(function(creds) {
console.log("Logged in with token"); console.log("Logged in with token");
return _clearStorage().then(() => { return _clearStorage().then(() => {
_persistCredentialsToLocalStorage({ _persistCredentialsToLocalStorage(creds);
userId: data.user_id,
deviceId: data.device_id,
accessToken: data.access_token,
homeserverUrl: queryParams.homeserver,
identityServerUrl: queryParams.identityServer,
guest: false,
});
return true; return true;
}); });
}).catch((err) => { }).catch((err) => {

View File

@ -1,6 +1,7 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd Copyright 2017 Vector Creations Ltd
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -17,7 +18,6 @@ limitations under the License.
import Matrix from "matrix-js-sdk"; import Matrix from "matrix-js-sdk";
import Promise from 'bluebird';
import url from 'url'; import url from 'url';
export default class Login { export default class Login {
@ -141,60 +141,20 @@ export default class Login {
}; };
Object.assign(loginParams, legacyParams); Object.assign(loginParams, legacyParams);
const client = this._createTemporaryClient();
const tryFallbackHs = (originalError) => { const tryFallbackHs = (originalError) => {
const fbClient = Matrix.createClient({ return sendLoginRequest(
baseUrl: self._fallbackHsUrl, self._fallbackHsUrl, this._isUrl, 'm.login.password', loginParams,
idBaseUrl: this._isUrl, ).catch((fallback_error) => {
});
return fbClient.login('m.login.password', loginParams).then(function(data) {
return Promise.resolve({
homeserverUrl: self._fallbackHsUrl,
identityServerUrl: self._isUrl,
userId: data.user_id,
deviceId: data.device_id,
accessToken: data.access_token,
});
}).catch((fallback_error) => {
console.log("fallback HS login failed", fallback_error); console.log("fallback HS login failed", fallback_error);
// throw the original error // throw the original error
throw originalError; throw originalError;
}); });
}; };
const tryLowercaseUsername = (originalError) => {
const loginParamsLowercase = Object.assign({}, loginParams, {
user: username.toLowerCase(),
identifier: {
user: username.toLowerCase(),
},
});
return client.login('m.login.password', loginParamsLowercase).then(function(data) {
return Promise.resolve({
homeserverUrl: self._hsUrl,
identityServerUrl: self._isUrl,
userId: data.user_id,
deviceId: data.device_id,
accessToken: data.access_token,
});
}).catch((fallback_error) => {
console.log("Lowercase username login failed", fallback_error);
// throw the original error
throw originalError;
});
};
let originalLoginError = null; let originalLoginError = null;
return client.login('m.login.password', loginParams).then(function(data) { return sendLoginRequest(
return Promise.resolve({ self._hsUrl, self._isUrl, 'm.login.password', loginParams,
homeserverUrl: self._hsUrl, ).catch((error) => {
identityServerUrl: self._isUrl,
userId: data.user_id,
deviceId: data.device_id,
accessToken: data.access_token,
});
}).catch((error) => {
originalLoginError = error; originalLoginError = error;
if (error.httpStatus === 403) { if (error.httpStatus === 403) {
if (self._fallbackHsUrl) { if (self._fallbackHsUrl) {
@ -202,22 +162,6 @@ export default class Login {
} }
} }
throw originalLoginError; throw originalLoginError;
}).catch((error) => {
// We apparently squash case at login serverside these days:
// https://github.com/matrix-org/synapse/blob/1189be43a2479f5adf034613e8d10e3f4f452eb9/synapse/handlers/auth.py#L475
// so this wasn't needed after all. Keeping the code around in case the
// the situation changes...
/*
if (
error.httpStatus === 403 &&
loginParams.identifier.type === 'm.id.user' &&
username.search(/[A-Z]/) > -1
) {
return tryLowercaseUsername(originalLoginError);
}
*/
throw originalLoginError;
}).catch((error) => { }).catch((error) => {
console.log("Login failed", error); console.log("Login failed", error);
throw error; throw error;
@ -239,3 +183,32 @@ export default class Login {
return client.getSsoLoginUrl(url.format(parsedUrl), loginType); return client.getSsoLoginUrl(url.format(parsedUrl), loginType);
} }
} }
/**
* Send a login request to the given server, and format the response
* as a MatrixClientCreds
*
* @param {string} hsUrl the base url of the Homeserver used to log in.
* @param {string} isUrl the base url of the default identity server
* @param {string} loginType the type of login to do
* @param {object} loginParams the parameters for the login
*
* @returns {MatrixClientCreds}
*/
export async function sendLoginRequest(hsUrl, isUrl, loginType, loginParams) {
const client = Matrix.createClient({
baseUrl: hsUrl,
idBaseUrl: isUrl,
});
const data = await client.login(loginType, loginParams);
return {
homeserverUrl: hsUrl,
identityServerUrl: isUrl,
userId: data.user_id,
deviceId: data.device_id,
accessToken: data.access_token,
};
}