2021-07-28 15:15:52 +02:00
|
|
|
import * as sdk from 'matrix-js-sdk';
|
|
|
|
import cons from '../state/cons';
|
|
|
|
import { getBaseUrl } from '../../util/matrixUtil';
|
|
|
|
|
|
|
|
async function login(username, homeserver, password) {
|
2021-07-29 10:23:50 +02:00
|
|
|
let baseUrl = null;
|
|
|
|
try {
|
|
|
|
baseUrl = await getBaseUrl(homeserver);
|
|
|
|
} catch (e) {
|
|
|
|
baseUrl = `https://${homeserver}`;
|
|
|
|
}
|
2021-07-28 15:15:52 +02:00
|
|
|
|
|
|
|
if (typeof baseUrl === 'undefined') throw new Error('Homeserver not found');
|
|
|
|
|
|
|
|
const client = sdk.createClient({ baseUrl });
|
|
|
|
|
|
|
|
const response = await client.login('m.login.password', {
|
2021-08-03 06:23:28 +02:00
|
|
|
identifier: {
|
|
|
|
type: 'm.id.user',
|
|
|
|
user: username,
|
|
|
|
},
|
2021-07-28 15:15:52 +02:00
|
|
|
password,
|
|
|
|
initial_device_display_name: cons.DEVICE_DISPLAY_NAME,
|
|
|
|
});
|
|
|
|
|
|
|
|
localStorage.setItem(cons.secretKey.ACCESS_TOKEN, response.access_token);
|
|
|
|
localStorage.setItem(cons.secretKey.DEVICE_ID, response.device_id);
|
|
|
|
localStorage.setItem(cons.secretKey.USER_ID, response.user_id);
|
2021-07-29 12:01:35 +02:00
|
|
|
localStorage.setItem(cons.secretKey.BASE_URL, response?.well_known?.['m.homeserver']?.base_url || baseUrl);
|
2021-07-28 15:15:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getAdditionalInfo(baseUrl, content) {
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/_matrix/client/r0/register`, {
|
|
|
|
method: 'POST',
|
|
|
|
body: JSON.stringify(content),
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json; charset=utf-8',
|
|
|
|
},
|
|
|
|
credentials: 'same-origin',
|
|
|
|
});
|
|
|
|
const data = await res.json();
|
|
|
|
return data;
|
|
|
|
} catch (e) {
|
|
|
|
throw new Error(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
async function verifyEmail(baseUrl, content) {
|
|
|
|
try {
|
2021-08-04 05:59:06 +02:00
|
|
|
const res = await fetch(`${baseUrl}/_matrix/client/r0/register/email/requestToken`, {
|
2021-07-28 15:15:52 +02:00
|
|
|
method: 'POST',
|
|
|
|
body: JSON.stringify(content),
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json; charset=utf-8',
|
|
|
|
},
|
|
|
|
credentials: 'same-origin',
|
|
|
|
});
|
|
|
|
const data = await res.json();
|
|
|
|
return data;
|
|
|
|
} catch (e) {
|
|
|
|
throw new Error(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let session = null;
|
|
|
|
let clientSecret = null;
|
|
|
|
let sid = null;
|
|
|
|
async function register(username, homeserver, password, email, recaptchaValue, terms, verified) {
|
|
|
|
const baseUrl = await getBaseUrl(homeserver);
|
|
|
|
|
|
|
|
if (typeof baseUrl === 'undefined') throw new Error('Homeserver not found');
|
|
|
|
|
|
|
|
const client = sdk.createClient({ baseUrl });
|
|
|
|
|
|
|
|
const isAvailable = await client.isUsernameAvailable(username);
|
|
|
|
if (!isAvailable) throw new Error('Username not available');
|
|
|
|
|
|
|
|
if (typeof recaptchaValue === 'string') {
|
|
|
|
await getAdditionalInfo(baseUrl, {
|
|
|
|
auth: {
|
|
|
|
type: 'm.login.recaptcha',
|
|
|
|
session,
|
|
|
|
response: recaptchaValue,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} else if (terms === true) {
|
|
|
|
await getAdditionalInfo(baseUrl, {
|
|
|
|
auth: {
|
|
|
|
type: 'm.login.terms',
|
|
|
|
session,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} else if (verified !== true) {
|
|
|
|
session = null;
|
|
|
|
clientSecret = client.generateClientSecret();
|
|
|
|
const verifyData = await verifyEmail(baseUrl, {
|
|
|
|
email,
|
|
|
|
client_secret: clientSecret,
|
|
|
|
send_attempt: 1,
|
|
|
|
});
|
|
|
|
if (typeof verifyData.error === 'string') {
|
|
|
|
throw new Error(verifyData.error);
|
|
|
|
}
|
|
|
|
sid = verifyData.sid;
|
|
|
|
}
|
|
|
|
|
|
|
|
const additionalInfo = await getAdditionalInfo(baseUrl, {
|
|
|
|
auth: { session: (session !== null) ? session : undefined },
|
|
|
|
});
|
|
|
|
session = additionalInfo.session;
|
|
|
|
if (typeof additionalInfo.completed === 'undefined' || additionalInfo.completed.length === 0) {
|
|
|
|
return ({
|
|
|
|
type: 'recaptcha',
|
|
|
|
public_key: additionalInfo.params['m.login.recaptcha'].public_key,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (additionalInfo.completed.find((process) => process === 'm.login.recaptcha') === 'm.login.recaptcha'
|
|
|
|
&& !additionalInfo.completed.find((process) => process === 'm.login.terms')) {
|
|
|
|
return ({
|
|
|
|
type: 'terms',
|
|
|
|
en: additionalInfo.params['m.login.terms'].policies.privacy_policy.en,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (verified || additionalInfo.completed.find((process) => process === 'm.login.terms') === 'm.login.terms') {
|
|
|
|
const tpc = {
|
|
|
|
client_secret: clientSecret,
|
|
|
|
sid,
|
|
|
|
};
|
|
|
|
const verifyData = await getAdditionalInfo(baseUrl, {
|
|
|
|
auth: {
|
|
|
|
session,
|
|
|
|
type: 'm.login.email.identity',
|
|
|
|
threepidCreds: tpc,
|
|
|
|
threepid_creds: tpc,
|
|
|
|
},
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
});
|
|
|
|
if (verifyData.errcode === 'M_UNAUTHORIZED') {
|
|
|
|
return { type: 'email' };
|
|
|
|
}
|
|
|
|
|
|
|
|
localStorage.setItem(cons.secretKey.ACCESS_TOKEN, verifyData.access_token);
|
|
|
|
localStorage.setItem(cons.secretKey.DEVICE_ID, verifyData.device_id);
|
|
|
|
localStorage.setItem(cons.secretKey.USER_ID, verifyData.user_id);
|
|
|
|
localStorage.setItem(cons.secretKey.BASE_URL, baseUrl);
|
|
|
|
return { type: 'done' };
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
export { login, register };
|