Introduce OLM Encryption (1.1.0)
This release includes breaking changes. The [`node-localstorage`](https://github.com/lmaccherone/node-localstorage) package was added and has replaced our use of [`file-system`](https://github.com/douzi8/file-system). The [`OLM`](https://gitlab.matrix.org/matrix-org/olm) package has also been added, so that we can support users who live on homeservers which require e2ee on direct messaging. The [`matrix-js-sdk`](https://github.com/matrix-org/matrix-js-sdk/) has been upgraded 7 major versions. A re-run of `yarn` or `yarn install` to re-install dependencies is required.
This commit is contained in:
commit
1a7d361b5d
30 changed files with 268 additions and 1419 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -11,11 +11,8 @@ yarn-error.log*
|
||||||
# Ignore config
|
# Ignore config
|
||||||
config.js
|
config.js
|
||||||
|
|
||||||
# Ignore JSON
|
# Ignore localstorage
|
||||||
timeline.json
|
keys
|
||||||
notification.json
|
|
||||||
matrix_auth.json
|
|
||||||
fediverse_auth.json
|
|
||||||
|
|
||||||
# Runtime data
|
# Runtime data
|
||||||
pids
|
pids
|
||||||
|
|
|
@ -37,7 +37,8 @@ Commands for the Fediverse include:
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
First, set up your config.js file, you can see config.example.js as an example. The Matrix & Fediverse login information is used to populate matrix_auth.json and fediverse_auth.json during your initial login. These tokens are then used on sequential logins.
|
First, set up your config.js file, you can see config.example.js as an example. The Matrix & Fediverse login information is then used to populate keys/matrix_auth and keys/fediverse_auth during your initial login. These tokens are then used on sequential logins.
|
||||||
|
|
||||||
1. `git clone https://github.com/vulet/ligh7hau5`
|
1. `git clone https://github.com/vulet/ligh7hau5`
|
||||||
2. `cd ligh7hau5 && yarn install`
|
2. `cd ligh7hau5 && yarn install`
|
||||||
3. `node main.js`
|
3. `node main.js`
|
||||||
|
|
66
auth.js
66
auth.js
|
@ -1,41 +1,58 @@
|
||||||
const sdk = require('matrix-js-sdk');
|
const { LocalStorageCryptoStore } = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store');
|
||||||
const axios = require('axios');
|
|
||||||
const fs = require('fs');
|
|
||||||
const registrar = require('./registrar.js');
|
|
||||||
|
|
||||||
module.exports.getMatrixToken = async () => {
|
module.exports.getMatrixToken = async () => {
|
||||||
matrixClient = sdk.createClient(registrar.config.matrix.domain);
|
matrixClient = sdk.createClient(config.matrix.domain);
|
||||||
matrixClient.loginWithPassword(registrar.config.matrix.user, registrar.config.matrix.password)
|
matrixClient.loginWithPassword(config.matrix.user, config.matrix.password)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
registrar.matrix_auth.access_token = response.access_token;
|
matrix_auth = {
|
||||||
registrar.matrix_auth.user_id = response.user_id;
|
user_id: response.user_id,
|
||||||
fs.writeFileSync('matrix_auth.json', JSON.stringify(response, null, 2));
|
access_token: response.access_token,
|
||||||
|
device_id: response.device_id,
|
||||||
|
};
|
||||||
|
localStorage.setItem('matrix_auth', JSON.stringify(response, null, 2));
|
||||||
|
}).then(() => {
|
||||||
|
matrixTokenLogin();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
matrixTokenLogin = async () => {
|
||||||
|
matrixClient = sdk.createClient({
|
||||||
|
baseUrl: config.matrix.domain,
|
||||||
|
accessToken: matrix_auth.access_token,
|
||||||
|
userId: matrix_auth.user_id,
|
||||||
|
deviceId: matrix_auth.device_id,
|
||||||
|
sessionStore: new sdk.WebStorageSessionStore(localStorage),
|
||||||
|
cryptoStore: new LocalStorageCryptoStore(localStorage),
|
||||||
|
});
|
||||||
|
matrixClient.initCrypto()
|
||||||
|
.then(() => {
|
||||||
|
if(!localStorage.getItem('crypto.device_data'))
|
||||||
|
return console.log(
|
||||||
|
'====================================================\n'+
|
||||||
|
'New OLM Encryption Keys created, please restart ligh7hau5.\n'+
|
||||||
|
'===================================================='
|
||||||
|
);
|
||||||
matrixClient.startClient();
|
matrixClient.startClient();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.matrixTokenLogin = async () => {
|
module.exports.matrixTokenLogin = matrixTokenLogin;
|
||||||
matrixClient = sdk.createClient({
|
|
||||||
baseUrl: registrar.config.matrix.domain,
|
|
||||||
accessToken: registrar.matrix_auth.access_token,
|
|
||||||
userId: registrar.matrix_auth.user_id,
|
|
||||||
timelineSupport: true,
|
|
||||||
});
|
|
||||||
matrixClient.startClient();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.registerFediverseApp = async () => {
|
module.exports.registerFediverseApp = async () => {
|
||||||
axios.post(`${registrar.config.fediverse.domain}/api/v1/apps`,
|
axios.post(`${config.fediverse.domain}/api/v1/apps`,
|
||||||
{
|
{
|
||||||
client_name: registrar.config.fediverse.client_name,
|
client_name: config.fediverse.client_name,
|
||||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
scopes: 'read write follow push',
|
scopes: 'read write follow push',
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
axios.post(`${registrar.config.fediverse.domain}/oauth/token`,
|
axios.post(`${config.fediverse.domain}/oauth/token`,
|
||||||
{
|
{
|
||||||
username: registrar.config.fediverse.username,
|
username: config.fediverse.username,
|
||||||
password: registrar.config.fediverse.password,
|
password: config.fediverse.password,
|
||||||
client_id: response.data.client_id,
|
client_id: response.data.client_id,
|
||||||
client_secret: response.data.client_secret,
|
client_secret: response.data.client_secret,
|
||||||
scope: 'read write follow push',
|
scope: 'read write follow push',
|
||||||
|
@ -43,8 +60,7 @@ module.exports.registerFediverseApp = async () => {
|
||||||
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
})
|
})
|
||||||
.then((tokens) => {
|
.then((tokens) => {
|
||||||
registrar.fediverse_auth.access_token = tokens.data.access_token;
|
localStorage.setItem('fediverse_auth', JSON.stringify(tokens.data, null, 2));
|
||||||
fs.writeFileSync('fediverse_auth.json', JSON.stringify(tokens.data, null, 2));
|
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
const qs = require('qs');
|
|
||||||
const axios = require('axios');
|
|
||||||
const { JSDOM } = require('jsdom');
|
const { JSDOM } = require('jsdom');
|
||||||
const registrar = require('../registrar.js');
|
const qs = require('qs');
|
||||||
|
|
||||||
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
||||||
|
|
||||||
|
@ -51,11 +49,10 @@ const arc1Str = str => `<em>Archiving page <code>${str}</code></em>`;
|
||||||
const arc2Str = (str, title, date) => `<em>Archived page <code><a href="https://${str}">${str}</code> [${date}]</em><br /><b>${title}</b>`;
|
const arc2Str = (str, title, date) => `<em>Archived page <code><a href="https://${str}">${str}</code> [${date}]</em><br /><b>${title}</b>`;
|
||||||
const arc3Str = str => `<em>Timed out <code>${str}</code></em>`;
|
const arc3Str = str => `<em>Timed out <code>${str}</code></em>`;
|
||||||
|
|
||||||
const run = async (matrixClient, { roomId }, userInput, rearchive, registrar) => {
|
const run = async (matrixClient, { roomId }, userInput, rearchive) => {
|
||||||
const config = registrar.config.archive;
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: `https://${config.domain}`,
|
baseURL: `https://${config.archive.domain}`,
|
||||||
headers: headers(config),
|
headers: headers(config.archive),
|
||||||
transformResponse: [],
|
transformResponse: [],
|
||||||
timeout: 10 * 1000
|
timeout: 10 * 1000
|
||||||
});
|
});
|
||||||
|
@ -65,9 +62,9 @@ const run = async (matrixClient, { roomId }, userInput, rearchive, registrar) =>
|
||||||
reply = await matrixClient.sendHtmlNotice(roomId, '', reqStr(userInput));
|
reply = await matrixClient.sendHtmlNotice(roomId, '', reqStr(userInput));
|
||||||
const { refresh, id, title, date } = await archive(instance, userInput, rearchive);
|
const { refresh, id, title, date } = await archive(instance, userInput, rearchive);
|
||||||
if (id)
|
if (id)
|
||||||
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.domain}${id}`, title, date));
|
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.archive.domain}${id}`, title, date));
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
const path = refresh.split(`https://${config.domain}`);
|
const path = refresh.split(`https://${config.archive.domain}`);
|
||||||
if (!path[1]) throw refresh;
|
if (!path[1]) throw refresh;
|
||||||
await editNoticeHTML(matrixClient, roomId, reply, arc1Str(refresh));
|
await editNoticeHTML(matrixClient, roomId, reply, arc1Str(refresh));
|
||||||
let tries = 30;
|
let tries = 30;
|
||||||
|
@ -75,11 +72,11 @@ const run = async (matrixClient, { roomId }, userInput, rearchive, registrar) =>
|
||||||
await sleep(10000);
|
await sleep(10000);
|
||||||
const { title, date, id } = await archive(instance, userInput);
|
const { title, date, id } = await archive(instance, userInput);
|
||||||
if (rearchive == false && title !== undefined)
|
if (rearchive == false && title !== undefined)
|
||||||
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.domain}${id}`, title, date));
|
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.archive.domain}${id}`, title, date));
|
||||||
const { request: { path: reqPath }, headers: { 'memento-datetime': rearchiveDate } } = await instance({ method: 'HEAD', url: path[1] })
|
const { request: { path: reqPath }, headers: { 'memento-datetime': rearchiveDate } } = await instance({ method: 'HEAD', url: path[1] })
|
||||||
.catch(e => ({ request: { path: path[1] } }));
|
.catch(e => ({ request: { path: path[1] } }));
|
||||||
if (rearchive == true && reqPath !== path[1])
|
if (rearchive == true && reqPath !== path[1])
|
||||||
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.domain}${reqPath}`, title, rearchiveDate));
|
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.archive.domain}${reqPath}`, title, rearchiveDate));
|
||||||
}
|
}
|
||||||
return await editNoticeHTML(matrixClient, roomId, reply, arc3Str(refresh));
|
return await editNoticeHTML(matrixClient, roomId, reply, arc3Str(refresh));
|
||||||
}
|
}
|
||||||
|
@ -94,4 +91,3 @@ const run = async (matrixClient, { roomId }, userInput, rearchive, registrar) =>
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.runQuery = run;
|
exports.runQuery = run;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses`,
|
url: `${config.fediverse.domain}/api/v1/statuses`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
data: { status: `@10grans@fedi.cc beg` },
|
data: { status: `@10grans@fedi.cc beg` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}/unfavourite`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}/unfavourite`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}/favourite`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}/favourite`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}/reblog`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}/reblog`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room) {
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, registrar) {
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
axios({
|
axios({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/timelines/home`,
|
url: `${config.fediverse.domain}/api/v1/timelines/home`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((events) => {
|
}).then((events) => {
|
||||||
const event = fs.readFileSync('timeline.json', 'utf8');
|
let lastEvent = JSON.parse(localStorage.getItem('timeline'));
|
||||||
fs.writeFileSync('timeline.json', events.data[0].created_at, 'utf8');
|
localStorage.setItem('timeline', JSON.stringify(events.data[0].created_at, null, 2));
|
||||||
if (event !== events.data[0].created_at) {
|
|
||||||
|
if (lastEvent !== events.data[0].created_at) {
|
||||||
if (events.data[0].reblog === null) {
|
if (events.data[0].reblog === null) {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/notice/${events.data[0].id}">${events.data[0].account.acct}</a>
|
`<b><a href="${config.fediverse.domain}/notice/${events.data[0].id}">${events.data[0].account.acct}</a>
|
||||||
<blockquote><i>${events.data[0].content}</i><br>
|
<blockquote><i>${events.data[0].content}</i><br>
|
||||||
${events.data[0].media_attachments.map(media =>
|
${events.data[0].media_attachments.map(media =>
|
||||||
`<a href="${media.remote_url}">`+`${media.description}`+'</a>'
|
`<a href="${media.remote_url}">`+`${media.description}`+'</a>'
|
||||||
|
@ -24,9 +22,9 @@ exports.runQuery = function (matrixClient, room, registrar) {
|
||||||
} else {
|
} else {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/${events.data[0].account.id}">
|
`<b><a href="${config.fediverse.domain}/${events.data[0].account.id}">
|
||||||
${events.data[0].account.acct}</a>
|
${events.data[0].account.acct}</a>
|
||||||
<font color="#7886D7">has <a href="${registrar.config.fediverse.domain}/notice/${events.data[0].id}">repeated</a>:
|
<font color="#7886D7">has <a href="${config.fediverse.domain}/notice/${events.data[0].id}">repeated</a>:
|
||||||
<blockquote><a href="${events.data[0].reblog.account.url}">${events.data[0].reblog.account.acct}</a></blockquote>
|
<blockquote><a href="${events.data[0].reblog.account.url}">${events.data[0].reblog.account.acct}</a></blockquote>
|
||||||
<blockquote>${events.data[0].content}<br>
|
<blockquote>${events.data[0].content}<br>
|
||||||
${events.data[0].media_attachments.map(media =>
|
${events.data[0].media_attachments.map(media =>
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
const fediverse_auth = JSON.parse(localStorage.getItem('fediverse_auth'));
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
axios.get(`${registrar.config.fediverse.domain}/api/v1/accounts/${userInput}`).then((findUID) => {
|
axios.get(`${config.fediverse.domain}/api/v1/accounts/${userInput}`).then((findUID) => {
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/accounts/${findUID.data.id}/follow`,
|
url: `${config.fediverse.domain}/api/v1/accounts/${findUID.data.id}/follow`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`Subscribed:
|
`Subscribed:
|
||||||
<blockquote>${registrar.config.fediverse.domain}/${response.data.id}`);
|
<blockquote>${config.fediverse.domain}/${response.data.id}`);
|
||||||
});
|
});
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const qs = require('qs');
|
const qs = require('qs');
|
||||||
const axios = require('axios');
|
|
||||||
const FormData = require('form-data');
|
const FormData = require('form-data');
|
||||||
|
|
||||||
const emojis = { public: '🌐', unlisted: '📝', private: '🔒️', direct: '✉️' };
|
const emojis = { public: '🌐', unlisted: '📝', private: '🔒️', direct: '✉️' };
|
||||||
|
@ -26,7 +25,7 @@ const mediaDownload = async (url, { whitelist, blacklist }) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mediaUpload = async ({ domain }, { data, filename, mimetype }, registrar) => {
|
const mediaUpload = async ({ domain }, { data, filename, mimetype }) => {
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append('file', data, {
|
form.append('file', data, {
|
||||||
filename: filename || 'upload',
|
filename: filename || 'upload',
|
||||||
|
@ -35,24 +34,24 @@ const mediaUpload = async ({ domain }, { data, filename, mimetype }, registrar)
|
||||||
const upload = await axios({
|
const upload = await axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${domain}/api/v1/media`,
|
url: `${domain}/api/v1/media`,
|
||||||
headers: form.getHeaders({ Authorization: `Bearer ${registrar.fediverse_auth.access_token}` }),
|
headers: form.getHeaders({ Authorization: `Bearer ${fediverse_auth.access_token}` }),
|
||||||
data: form,
|
data: form,
|
||||||
});
|
});
|
||||||
if(upload.statusText !== 'OK') throw upload;
|
if(upload.statusText !== 'OK') throw upload;
|
||||||
return upload.data.id;
|
return upload.data.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const run = async (matrixClient, { roomId }, content, replyId, mediaURL, subject, registrar) => {
|
const run = async (matrixClient, { roomId }, content, replyId, mediaURL, subject) => {
|
||||||
let mediaId = null;
|
let mediaId = null;
|
||||||
const fediverse = registrar.config.fediverse;
|
const fediverse = config.fediverse;
|
||||||
if(mediaURL) {
|
if(mediaURL) {
|
||||||
const media = await mediaDownload(mediaURL, registrar.config.fediverse.mimetypes);
|
const media = await mediaDownload(mediaURL, fediverse.mimetypes);
|
||||||
mediaId = await mediaUpload(fediverse, media, registrar);
|
mediaId = await mediaUpload(fediverse, media);
|
||||||
}
|
}
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${fediverse.domain}/api/v1/statuses`,
|
url: `${fediverse.domain}/api/v1/statuses`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}`, 'Content-Type': 'application/x-www-form-urlencoded' },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}`, 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
data : qs.stringify({
|
data : qs.stringify({
|
||||||
status: content,
|
status: content,
|
||||||
content_type: `text/markdown`,
|
content_type: `text/markdown`,
|
||||||
|
@ -64,13 +63,13 @@ const run = async (matrixClient, { roomId }, content, replyId, mediaURL, subject
|
||||||
return matrixClient.sendHtmlNotice(roomId, '', `<a href="${response.data.url}">${response.data.id}</a>`);
|
return matrixClient.sendHtmlNotice(roomId, '', `<a href="${response.data.url}">${response.data.id}</a>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.runQuery = async (client, room, userInput, registrar, { isReply, hasMedia, hasSubject }) => {
|
exports.runQuery = async (client, room, userInput, { isReply, hasMedia, hasSubject }) => {
|
||||||
try {
|
try {
|
||||||
const chunks = userInput.trim().split(' ');
|
const chunks = userInput.trim().split(' ');
|
||||||
if(!chunks.length || chunks.length < !!isReply + !!hasMedia) throw '';
|
if(!chunks.length || chunks.length < !!isReply + !!hasMedia) throw '';
|
||||||
let replyId = null;
|
let replyId = null;
|
||||||
let mediaURL = null;
|
let mediaURL = null;
|
||||||
const subject = hasSubject ? registrar.config.fediverse.subject : null;
|
const subject = hasSubject ? fediverse.subject : null;
|
||||||
if(isReply) {
|
if(isReply) {
|
||||||
replyId = chunks[0];
|
replyId = chunks[0];
|
||||||
chunks.shift();
|
chunks.shift();
|
||||||
|
@ -79,13 +78,13 @@ exports.runQuery = async (client, room, userInput, registrar, { isReply, hasMedi
|
||||||
let url = new URL(chunks[0]);
|
let url = new URL(chunks[0]);
|
||||||
chunks.shift();
|
chunks.shift();
|
||||||
if(url.protocol === 'mxc:' && url.hostname && url.pathname)
|
if(url.protocol === 'mxc:' && url.hostname && url.pathname)
|
||||||
url = new URL(`${registrar.config.matrix.domain}/_matrix/media/r0/download/${url.hostname}${url.pathname}`);
|
url = new URL(`${config.matrix.domain}/_matrix/media/r0/download/${url.hostname}${url.pathname}`);
|
||||||
if(url.protocol !== 'https:') throw '';
|
if(url.protocol !== 'https:') throw '';
|
||||||
if(!registrar.config.matrix.domains.includes(url.hostname)) throw '';
|
if(!config.matrix.domains.includes(url.hostname)) throw '';
|
||||||
if(!/^\/_matrix\/media\/r0\/download\/[^/]+\/[^/]+\/?$/.test(url.pathname)) throw '';
|
if(!/^\/_matrix\/media\/r0\/download\/[^/]+\/[^/]+\/?$/.test(url.pathname)) throw '';
|
||||||
mediaURL = url.toString();
|
mediaURL = url.toString();
|
||||||
}
|
}
|
||||||
return await run(client, room, chunks.join(' '), replyId, mediaURL, subject, registrar);
|
return await run(client, room, chunks.join(' '), replyId, mediaURL, subject);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses`,
|
url: `${config.fediverse.domain}/api/v1/statuses`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
data: {
|
data: {
|
||||||
status: `@mordekai ${userInput}`,
|
status: `@mordekai ${userInput}`,
|
||||||
content_type: `text/markdown`,
|
content_type: `text/markdown`,
|
||||||
|
|
|
@ -1,49 +1,45 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room) {
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, registrar) {
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
axios({
|
axios({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/notifications`,
|
url: `${config.fediverse.domain}/api/v1/notifications`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((notifications) => {
|
}).then((events) => {
|
||||||
const event = fs.readFileSync('notification.json', 'utf8');
|
let lastEvent = JSON.parse(localStorage.getItem('notifications'));
|
||||||
fs.writeFileSync('notification.json', notifications.data[0].created_at, 'utf8');
|
localStorage.setItem('notifications', JSON.stringify(events.data[0].created_at, null, 2));
|
||||||
|
if (lastEvent !== events.data[0].created_at) {
|
||||||
if (event !== notifications.data[0].created_at) {
|
if (events.data[0].type === 'follow') {
|
||||||
if (notifications.data[0].type === 'follow') {
|
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/${notifications.data[0].account.id}">
|
`<b><a href="${config.fediverse.domain}/${events.data[0].account.id}">
|
||||||
${notifications.data[0].account.acct}</a></b>
|
${events.data[0].account.acct}</a></b>
|
||||||
<font color="#03b381"><b>has followed you.</b></font>
|
<font color="#03b381"><b>has followed you.</b></font>
|
||||||
<br><i>${notifications.data[0].account.note}</i>`);
|
<br><i>${events.data[0].account.note}</i>`);
|
||||||
} else if (notifications.data[0].type === 'favourite') {
|
} else if (events.data[0].type === 'favourite') {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/${notifications.data[0].account.id}">
|
`<b><a href="${config.fediverse.domain}/${events.data[0].account.id}">
|
||||||
${notifications.data[0].account.acct}</a></b>
|
${events.data[0].account.acct}</a></b>
|
||||||
<font color="#03b381"><b>has <a href="${notifications.data[0].status.uri}">favorited</a>
|
<font color="#03b381"><b>has <a href="${events.data[0].status.uri}">favorited</a>
|
||||||
your post:</b></font>
|
your post:</b></font>
|
||||||
<br><blockquote><i><b>${notifications.data[0].status.content}</i></b></blockquote>`);
|
<br><blockquote><i><b>${events.data[0].status.content}</i></b></blockquote>`);
|
||||||
} else if (notifications.data[0].type === 'mention') {
|
} else if (events.data[0].type === 'mention') {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/${notifications.data[0].account.id}">
|
`<b><a href="${config.fediverse.domain}/${events.data[0].account.id}">
|
||||||
${notifications.data[0].account.acct}</a></b>
|
${events.data[0].account.acct}</a></b>
|
||||||
<font color="#03b381"><b>has <a href="${notifications.data[0].status.uri}">mentioned</a>
|
<font color="#03b381"><b>has <a href="${events.data[0].status.uri}">mentioned</a>
|
||||||
you:</b></font><br><blockquote><i><b>${notifications.data[0].status.content}
|
you:</b></font><br><blockquote><i><b>${events.data[0].status.content}
|
||||||
<br>(id: ${notifications.data[0].status.id}) ${registrar.media.visibilityEmoji(notifications.data[0].status.visibility)}</i></b>
|
<br>(id: ${events.data[0].status.id}) ${registrar.media.visibilityEmoji(events.data[0].status.visibility)}</i></b>
|
||||||
</blockquote>`);
|
</blockquote>`);
|
||||||
} else if (notifications.data[0].type === 'reblog') {
|
} else if (events.data[0].type === 'reblog') {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/${notifications.data[0].account.id}">
|
`<b><a href="${config.fediverse.domain}/${events.data[0].account.id}">
|
||||||
${notifications.data[0].account.acct}</a></b>
|
${events.data[0].account.acct}</a></b>
|
||||||
<font color="#03b381"><b>has <a href="${notifications.data[0].status.uri}">repeated</a>
|
<font color="#03b381"><b>has <a href="${events.data[0].status.uri}">repeated</a>
|
||||||
your post:</b></font><br>
|
your post:</b></font><br>
|
||||||
<blockquote><i><b>${notifications.data[0].status.content}</i></b></blockquote>`);
|
<blockquote><i><b>${events.data[0].status.content}</i></b></blockquote>`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}/pin`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}/pin`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`Pinned:
|
`Pinned:
|
||||||
<blockquote><i><a href="${registrar.config.fediverse.domain}/notice/${response.data.id}">
|
<blockquote><i><a href="${config.fediverse.domain}/notice/${response.data.id}">
|
||||||
${response.data.content}</a></i>
|
${response.data.content}</a></i>
|
||||||
</blockquote>`);
|
</blockquote>`);
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses`,
|
url: `${config.fediverse.domain}/api/v1/statuses`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
data: { status: userInput, content_type: `text/markdown` },
|
data: { status: userInput, content_type: `text/markdown` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, address, flaggedInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, address, flaggedInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses`,
|
url: `${config.fediverse.domain}/api/v1/statuses`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
data: { status: flaggedInput, in_reply_to_id: address, content_type: `text/markdown` },
|
data: { status: flaggedInput, in_reply_to_id: address, content_type: `text/markdown` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput, ) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`<b><a href="${registrar.config.fediverse.domain}/notice/${response.data.id}">${response.data.account.acct}</a>
|
`<b><a href="${config.fediverse.domain}/notice/${response.data.id}">${response.data.account.acct}</a>
|
||||||
<blockquote><i>${response.data.content}<br>
|
<blockquote><i>${response.data.content}<br>
|
||||||
${response.data.media_attachments.map(media =>
|
${response.data.media_attachments.map(media =>
|
||||||
`<a href="${media.remote_url}"><b>${media.description}</b></a>`)
|
`<a href="${media.remote_url}"><b>${media.description}</b></a>`)
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, address, flaggedInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, address, flaggedInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses`,
|
url: `${config.fediverse.domain}/api/v1/statuses`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
data: { status: `@10grans@fedi.cc tip `+ flaggedInput + ` to `+address },
|
data: { status: `@10grans@fedi.cc tip `+ flaggedInput + ` to `+address },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
axios.get(`${config.fediverse.domain}/api/v1/accounts/${userInput}`).then((findUID) => {
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios.get(`${registrar.config.fediverse.domain}/api/v1/accounts/${userInput}`).then((findUID) => {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/accounts/${findUID.data.id}/unfollow`,
|
url: `${config.fediverse.domain}/api/v1/accounts/${findUID.data.id}/unfollow`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`Unsubscribed:
|
`Unsubscribed:
|
||||||
<blockquote>${registrar.config.fediverse.domain}/${response.data.id}`);
|
<blockquote>${config.fediverse.domain}/${response.data.id}`);
|
||||||
});
|
});
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
const axios = require('axios');
|
exports.runQuery = function (matrixClient, room, userInput) {
|
||||||
|
|
||||||
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
|
||||||
axios({
|
axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${registrar.config.fediverse.domain}/api/v1/statuses/${userInput}/unpin`,
|
url: `${config.fediverse.domain}/api/v1/statuses/${userInput}/unpin`,
|
||||||
headers: { Authorization: `Bearer ${registrar.fediverse_auth.access_token}` },
|
headers: { Authorization: `Bearer ${fediverse_auth.access_token}` },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
`Unpinned:
|
`Unpinned:
|
||||||
<blockquote><i><a href="${registrar.config.fediverse.domain}/notice/${response.data.id}">
|
<blockquote><i><a href="${config.fediverse.domain}/notice/${response.data.id}">
|
||||||
${response.data.content}</a></i>
|
${response.data.content}</a></i>
|
||||||
</blockquote>`);
|
</blockquote>`);
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,11 +2,10 @@ exports.runQuery = function (matrixClient, room) {
|
||||||
matrixClient.sendHtmlNotice(room.roomId,
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
'',
|
'',
|
||||||
'<blockquote><b>fediverse commands<br>'
|
'<blockquote><b>fediverse commands<br>'
|
||||||
+ '+post [your message] : post<br>'
|
+ '+plemara [your message] : post<br>'
|
||||||
+ '+redact [post id] : delete post<br>'
|
+ '+redact [post id] : delete post<br>'
|
||||||
+ '+follow [user id] : follow<br>'
|
+ '+follow [user id] : follow<br>'
|
||||||
+ '+unfollow [user id] : unfollow<br>'
|
+ '+unfollow [user id] : unfollow<br>'
|
||||||
+ '+media [homeserver image URL or MXC] [optional message] : post media<br>'
|
|
||||||
+ '+copy [post id] : repeat/repost/retweet<br>'
|
+ '+copy [post id] : repeat/repost/retweet<br>'
|
||||||
+ '+reply [post id] [content] : reply to post<br>'
|
+ '+reply [post id] [content] : reply to post<br>'
|
||||||
+ '+tip [@user@fedi.url] [amount] : tip 10grans<br>'
|
+ '+tip [@user@fedi.url] [amount] : tip 10grans<br>'
|
||||||
|
@ -19,8 +18,7 @@ exports.runQuery = function (matrixClient, room) {
|
||||||
+ '+archive [URL] : archive content<br>'
|
+ '+archive [URL] : archive content<br>'
|
||||||
+ '+rearchive [URL] : re-archive content<br>'
|
+ '+rearchive [URL] : re-archive content<br>'
|
||||||
+ '+nitter [status URL] : redirect twitter to nitter, also embed tweet<br>'
|
+ '+nitter [status URL] : redirect twitter to nitter, also embed tweet<br>'
|
||||||
+ '+invidious [video URL] : redirect youtube to invidious, also embed description<br>'
|
+ '+invidious [video URL] : redirect youtube to invidious, also embed description</b><br></blockquote>'
|
||||||
+ '+proxy [twitter/youtube]: both +nitter and +invidious commands combined</b><br></blockquote>'
|
|
||||||
+ '<blockquote><b>--- <i>Contributors🐱</i> ---</b><br>'
|
+ '<blockquote><b>--- <i>Contributors🐱</i> ---</b><br>'
|
||||||
+ '<b>CRYPTOMOONERS</b><br>'
|
+ '<b>CRYPTOMOONERS</b><br>'
|
||||||
+ '<b><i>docs by LINT</i></b></blockquote>');
|
+ '<b><i>docs by LINT</i></b></blockquote>');
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
const axios = require('axios');
|
|
||||||
|
|
||||||
const headers = ({ domain, userAgent }) => ({
|
const headers = ({ domain, userAgent }) => ({
|
||||||
'Host': `${domain}`,
|
'Host': `${domain}`,
|
||||||
'User-Agent': `${userAgent}`
|
'User-Agent': `${userAgent}`
|
||||||
|
@ -31,28 +29,28 @@ const card = (video, base, path) =>
|
||||||
`<br />(${video.date})</b> <br />
|
`<br />(${video.date})</b> <br />
|
||||||
</blockquote>`;
|
</blockquote>`;
|
||||||
|
|
||||||
const run = async (matrixClient, { roomId }, userInput, registrar) => {
|
const run = async (matrixClient, { roomId }, userInput) => {
|
||||||
const config = registrar.config.invidious;
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: `https://${config.domain}/api/v1/videos/`,
|
baseURL: `https://${config.invidious.domain}/api/v1/videos/`,
|
||||||
headers: headers(config),
|
headers: headers(config.invidious),
|
||||||
transformResponse: [],
|
transformResponse: [],
|
||||||
timeout: 10 * 1000
|
timeout: 10 * 1000
|
||||||
});
|
});
|
||||||
const video = await invidious(instance, userInput);
|
const video = await invidious(instance, userInput);
|
||||||
return await matrixClient.sendHtmlNotice(roomId, '', card(video, `https://${config.domain}`, userInput));
|
return await matrixClient.sendHtmlNotice(roomId, '', card(video, `https://${config.invidious.domain}`, userInput));
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.runQuery = async (client, room, userInput, registrar) => {
|
exports.runQuery = async (client, room, userInput) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(userInput);
|
const url = new URL(userInput);
|
||||||
if(!registrar.config.invidious.domains.includes(url.hostname)) throw '';
|
if(!config.invidious.domains.includes(url.hostname)) throw '';
|
||||||
if(/^\/[\w-]{11}$/.test(url.pathname))
|
if(/^\/[\w-]{11}$/.test(url.pathname))
|
||||||
return await run(client, room, url.pathname.slice(1), registrar);
|
return await run(client, room, url.pathname.slice(1));
|
||||||
const params = new URLSearchParams(url.search).get("v");
|
const params = new URLSearchParams(url.search).get("v");
|
||||||
if(!/^[\w-]{11}$/.test(params)) throw '';
|
if(!/^[\w-]{11}$/.test(params)) throw '';
|
||||||
return await run(client, room, params, registrar);
|
return await run(client, room, params);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
const axios = require('axios');
|
|
||||||
const { JSDOM } = require("jsdom");
|
const { JSDOM } = require("jsdom");
|
||||||
|
|
||||||
const headers = ({ domain, userAgent }) => ({
|
const headers = ({ domain, userAgent }) => ({
|
||||||
|
@ -50,24 +49,23 @@ const card = (tweet, base, check, path) =>
|
||||||
(tweet.hasAttachments ? '<blockquote><b>This tweet has attached media.</b></blockquote>' : '') +
|
(tweet.hasAttachments ? '<blockquote><b>This tweet has attached media.</b></blockquote>' : '') +
|
||||||
(tweet.isReply ? tweet.isReply === 'unavailable' ? '<blockquote>Replied Tweet is unavailable</blockquote>' : `<blockquote><b><a href="${base}${tweet.isReply.path}">Replied Tweet</a></b><br /><b><i>${tweet.isReply.text.replace('\n', '<br />')}</i></b></blockquote>` : '') +
|
(tweet.isReply ? tweet.isReply === 'unavailable' ? '<blockquote>Replied Tweet is unavailable</blockquote>' : `<blockquote><b><a href="${base}${tweet.isReply.path}">Replied Tweet</a></b><br /><b><i>${tweet.isReply.text.replace('\n', '<br />')}</i></b></blockquote>` : '') +
|
||||||
(tweet.quote ? `<blockquote><b><a href="${base}${tweet.quote.path}">Quoted Tweet</a></b><br /><b><i>${tweet.quote.text.replace('\n', '<br />')}</i></b></blockquote>` : '');
|
(tweet.quote ? `<blockquote><b><a href="${base}${tweet.quote.path}">Quoted Tweet</a></b><br /><b><i>${tweet.quote.text.replace('\n', '<br />')}</i></b></blockquote>` : '');
|
||||||
const run = async (matrixClient, { roomId }, userInput, registrar) => {
|
const run = async (matrixClient, { roomId }, userInput) => {
|
||||||
const config = registrar.config.nitter;
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: `https://${config.domain}`,
|
baseURL: `https://${config.nitter.domain}`,
|
||||||
headers: headers(config),
|
headers: headers(config.nitter),
|
||||||
transformResponse: [],
|
transformResponse: [],
|
||||||
timeout: 10 * 1000
|
timeout: 10 * 1000
|
||||||
});
|
});
|
||||||
const tweet = await nitter(instance, userInput);
|
const tweet = await nitter(instance, userInput);
|
||||||
return await matrixClient.sendHtmlNotice(roomId, '', card(tweet, `https://${config.domain}`, config.check, userInput));
|
return await matrixClient.sendHtmlNotice(roomId, '', card(tweet, `https://${config.nitter.domain}`, config.nitter.check, userInput));
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.runQuery = async (client, room, userInput, registrar) => {
|
exports.runQuery = async (client, room, userInput) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(userInput);
|
const url = new URL(userInput);
|
||||||
if(!registrar.config.nitter.domains.includes(url.hostname)) throw '';
|
if(!config.nitter.domains.includes(url.hostname)) throw '';
|
||||||
if(!/^\/[^/]+\/status\/\d+\/?$/.test(url.pathname)) throw '';
|
if(!/^\/[^/]+\/status\/\d+\/?$/.test(url.pathname)) throw '';
|
||||||
return await run(client, room, url.pathname, registrar);
|
return await run(client, room, url.pathname);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"access_token": "",
|
|
||||||
"created_at": 0,
|
|
||||||
"expires_in": 0,
|
|
||||||
"me": "",
|
|
||||||
"refresh_token": "",
|
|
||||||
"scope": "",
|
|
||||||
"token_type": ""
|
|
||||||
}
|
|
38
main.js
38
main.js
|
@ -1,15 +1,15 @@
|
||||||
const registrar = require('./registrar.js');
|
global.registrar = require('./registrar.js');
|
||||||
const auth = require('./auth.js');
|
|
||||||
|
|
||||||
registrar.matrix_auth.access_token ? auth.matrixTokenLogin() : auth.getMatrixToken();
|
matrix_auth.access_token ? auth.matrixTokenLogin() : auth.getMatrixToken();
|
||||||
if (!registrar.fediverse_auth.access_token && registrar.config.fediverse.username) auth.registerFediverseApp();
|
if (!fediverse_auth.access_token && config.fediverse.username) auth.registerFediverseApp();
|
||||||
|
|
||||||
matrixClient.on('RoomMember.membership', (event, member) => {
|
matrixClient.on('RoomMember.membership', (event, member) => {
|
||||||
if (member.membership === 'invite' && member.userId === matrixClient.credentials.userId) {
|
if (member.membership === 'invite' && member.userId === matrixClient.credentials.userId) {
|
||||||
matrixClient.joinRoom(member.roomId).done(() => {
|
matrixClient.joinRoom(member.roomId).then(() => {
|
||||||
console.log('Auto-joined %s', member.roomId);
|
console.log('Auto-joined %s', member.roomId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (member.membership === 'leave' && member.userId === matrixClient.credentials.userId) {
|
if (member.membership === 'leave' && member.userId === matrixClient.credentials.userId) {
|
||||||
matrixClient.forget(member.roomId).then(() => {
|
matrixClient.forget(member.roomId).then(() => {
|
||||||
console.log('Kicked %s', member.roomId);
|
console.log('Kicked %s', member.roomId);
|
||||||
|
@ -17,14 +17,15 @@ matrixClient.on('RoomMember.membership', (event, member) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
matrixClient.on('Room.timeline', (event, room, toStartOfTimeline) => {
|
matrixClient.on('Room.timeline', async function (event, room, member, toStartOfTimeline) {
|
||||||
if (toStartOfTimeline) return;
|
if (toStartOfTimeline) return;
|
||||||
|
if (event.isEncrypted()) await event._decryptionPromise;
|
||||||
if (event.getType() !== 'm.room.message') return;
|
if (event.getType() !== 'm.room.message') return;
|
||||||
if (event.getSender() === matrixClient.credentials.userId) return;
|
if (event.getSender() === matrixClient.credentials.userId) return;
|
||||||
if (event.event.unsigned.age > 10000) return;
|
if (event.event.unsigned.age > 10000) return;
|
||||||
if (event.event.content.body.charAt(0) === '+') {
|
if (event.getContent().body.charAt(0) === '+') {
|
||||||
console.log(`Logs: ${event.event.sender} - ${event.event.content.body}`);
|
console.log(`Logs: ${event.event.sender} - ${event.getContent().body}`);
|
||||||
let args = event.event.content.body.slice(1).trim().split(/ +/g);
|
let args = event.getContent().body.slice(1).trim().split(/ +/g);
|
||||||
let command = args.shift().toLowerCase();
|
let command = args.shift().toLowerCase();
|
||||||
const userInput = args.join(' ');
|
const userInput = args.join(' ');
|
||||||
const flaggedInput = userInput.substr(userInput.indexOf(' ') + 1);
|
const flaggedInput = userInput.substr(userInput.indexOf(' ') + 1);
|
||||||
|
@ -35,19 +36,19 @@ matrixClient.on('Room.timeline', (event, room, toStartOfTimeline) => {
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case 'config':
|
case 'config':
|
||||||
return;
|
return;
|
||||||
case 'help': case 'beg': case 'flood': case 'notify':
|
case 'help': case 'beg': case 'flood': case 'asdf':
|
||||||
args.push(matrixClient, room, registrar);
|
args.push(matrixClient, room);
|
||||||
break;
|
break;
|
||||||
case 'tip':
|
case 'tip':
|
||||||
args.push(matrixClient, room, address, flaggedInput, registrar);
|
args.push(matrixClient, room, address, flaggedInput);
|
||||||
break;
|
break;
|
||||||
case 'archive': case 'rearchive':
|
case 'archive': case 'rearchive':
|
||||||
args.push(matrixClient, room, userInput, !!~command.indexOf('re'), registrar);
|
args.push(matrixClient, room, userInput, !!~command.indexOf('re'));
|
||||||
command = 'archive';
|
command = 'archive';
|
||||||
break;
|
break;
|
||||||
case 'post': case 'reply': case 'media': case 'mediareply':
|
case 'post': case 'reply': case 'media': case 'mediareply':
|
||||||
case 'random': case 'randomreply': case 'randommedia': case 'randommediareply':
|
case 'random': case 'randomreply': case 'randommedia': case 'randommediareply':
|
||||||
args.push(matrixClient, room, userInput, registrar, {
|
args.push(matrixClient, room, userInput, {
|
||||||
isReply: !!~command.indexOf('reply'),
|
isReply: !!~command.indexOf('reply'),
|
||||||
hasMedia: !!~command.indexOf('media'),
|
hasMedia: !!~command.indexOf('media'),
|
||||||
hasSubject: !!~command.indexOf('random'),
|
hasSubject: !!~command.indexOf('random'),
|
||||||
|
@ -57,17 +58,16 @@ matrixClient.on('Room.timeline', (event, room, toStartOfTimeline) => {
|
||||||
case 'proxy':
|
case 'proxy':
|
||||||
try {
|
try {
|
||||||
const url = new URL(userInput);
|
const url = new URL(userInput);
|
||||||
command = registrar.config.invidious.domains.includes(url.hostname)
|
command = config.invidious.domains.includes(url.hostname)
|
||||||
? 'invidious'
|
? 'invidious'
|
||||||
: registrar.config.nitter.domains.includes(url.hostname)
|
: config.nitter.domains.includes(url.hostname)
|
||||||
? 'nitter'
|
? 'nitter'
|
||||||
: 'proxy';
|
: 'proxy';
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
//fallthrough
|
//fallthrough
|
||||||
default:
|
default:
|
||||||
args.push(matrixClient, room, userInput, registrar);
|
args.push(matrixClient, room, userInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
registrar[command] && registrar[command].runQuery.apply(null, args);
|
registrar[command] && registrar[command].runQuery.apply(null, args);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"user_id": "",
|
|
||||||
"access_token": "",
|
|
||||||
"home_server": "",
|
|
||||||
"device_id": ""
|
|
||||||
}
|
|
16
package.json
16
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ligh7hau5",
|
"name": "ligh7hau5",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"description": "A Matrix to Fediverse client",
|
"description": "A Matrix to Fediverse client",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -19,14 +19,12 @@
|
||||||
"homepage": "https://github.com/vulet/lighthau5#readme",
|
"homepage": "https://github.com/vulet/lighthau5#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"file-system": "^2.2.2",
|
|
||||||
"form-data": "^3.0.0",
|
"form-data": "^3.0.0",
|
||||||
"jsdom": "^16.2.2",
|
"jsdom": "^16.4.0",
|
||||||
"matrix-js-sdk": "^2.4.6"
|
"matrix-js-sdk": "^9.5.1",
|
||||||
|
"node-localstorage": "^2.1.6",
|
||||||
|
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
|
||||||
|
"qs": "^6.9.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {}
|
||||||
"eslint": "^5.16.0",
|
|
||||||
"eslint-config-airbnb-base": "^13.1.0",
|
|
||||||
"eslint-plugin-import": "^2.17.3"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
26
registrar.js
26
registrar.js
|
@ -1,16 +1,24 @@
|
||||||
const fs = require('fs');
|
global.Olm = require('olm');
|
||||||
|
global.sdk = require('matrix-js-sdk');
|
||||||
|
global.axios = require('axios');
|
||||||
|
global.config = require('./config.js');
|
||||||
|
global.auth = require('./auth.js');
|
||||||
|
|
||||||
//initializers
|
const { LocalStorage } = require('node-localstorage');
|
||||||
if (!fs.existsSync('fediverse_auth.json')) fs.copyFileSync('fediverse_auth.example.json', 'fediverse_auth.json');
|
global.localStorage = new LocalStorage('./keys');
|
||||||
if (!fs.existsSync('matrix_auth.json')) fs.copyFileSync('matrix_auth.example.json', 'matrix_auth.json');
|
if (!localStorage.getItem('matrix_auth')){
|
||||||
if (!fs.existsSync('config.js')) fs.copyFileSync('config.example.js', 'config.js');
|
localStorage.clear();
|
||||||
if (!fs.existsSync('timeline.json')) fs.writeFileSync('timeline.json', 0);
|
localStorage.setItem('matrix_auth', "{}");
|
||||||
if (!fs.existsSync('notification.json')) fs.writeFileSync('notification.json', 0);
|
}
|
||||||
|
if (!localStorage.getItem('fediverse_auth')) localStorage.setItem('fediverse_auth', "{}");
|
||||||
|
if (!localStorage.getItem('timeline')) localStorage.setItem('timeline', "{}");
|
||||||
|
if (!localStorage.getItem('notifications')) localStorage.setItem('notifications', "{}");
|
||||||
|
|
||||||
|
global.matrix_auth = JSON.parse(localStorage.getItem('matrix_auth'));
|
||||||
|
global.fediverse_auth = JSON.parse(localStorage.getItem('fediverse_auth'));
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
config: require('./config.js'),
|
config: require('./config.js'),
|
||||||
fediverse_auth: require('./fediverse_auth.json'),
|
|
||||||
matrix_auth: require('./matrix_auth.json'),
|
|
||||||
archive: require('./commands/archive.js'),
|
archive: require('./commands/archive.js'),
|
||||||
invidious: require('./commands/invidious.js'),
|
invidious: require('./commands/invidious.js'),
|
||||||
nitter: require('./commands/nitter.js'),
|
nitter: require('./commands/nitter.js'),
|
||||||
|
|
Loading…
Reference in a new issue