forked from Mirrors/doipjs
Remove proxy functionality
This commit is contained in:
parent
f46b32528d
commit
421f907206
9 changed files with 3 additions and 739 deletions
58
.drone.yml
58
.drone.yml
|
@ -41,61 +41,3 @@ depends_on:
|
||||||
trigger:
|
trigger:
|
||||||
event:
|
event:
|
||||||
- tag
|
- tag
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: publish-docker-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: publish latest proxy container
|
|
||||||
image: plugins/docker
|
|
||||||
settings:
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
dockerfile: docker/proxy/Dockerfile
|
|
||||||
repo: keyoxide/doip-proxy
|
|
||||||
tags: latest
|
|
||||||
- name: build tag proxy container
|
|
||||||
image: plugins/docker
|
|
||||||
settings:
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
dockerfile: docker/proxy/Dockerfile
|
|
||||||
repo: keyoxide/doip-proxy
|
|
||||||
auto_tag: true
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- test
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
event:
|
|
||||||
- tag
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: publish-docker-dev
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build dev proxy container
|
|
||||||
image: plugins/docker
|
|
||||||
settings:
|
|
||||||
username:
|
|
||||||
from_secret: docker_username
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
dockerfile: docker/proxy/Dockerfile
|
|
||||||
repo: keyoxide/doip-proxy
|
|
||||||
tags: dev
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- test
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
- main
|
|
||||||
event:
|
|
||||||
- push
|
|
|
@ -19,4 +19,3 @@ yarn.lock
|
||||||
\.gitignore
|
\.gitignore
|
||||||
\.licenseignore
|
\.licenseignore
|
||||||
\.drone.yml
|
\.drone.yml
|
||||||
Dockerfile
|
|
|
@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Changed
|
### Changed
|
||||||
- Allow ActivityPub verification through posts
|
- Allow ActivityPub verification through posts
|
||||||
- Improve type consistency
|
- Improve type consistency
|
||||||
|
### Removed
|
||||||
|
- Proxy server code
|
||||||
|
|
||||||
## [0.17.5] - 2022-11-14
|
## [0.17.5] - 2022-11-14
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
FROM node:16-alpine
|
|
||||||
WORKDIR /app
|
|
||||||
COPY . .
|
|
||||||
RUN yarn --production --pure-lockfile
|
|
||||||
EXPOSE 3000
|
|
||||||
CMD yarn run proxy
|
|
|
@ -1,4 +0,0 @@
|
||||||
# doip-proxy
|
|
||||||
|
|
||||||
Documentation on how to use this container:
|
|
||||||
https://docs.keyoxide.org/advanced/self-hosting/
|
|
|
@ -51,8 +51,6 @@
|
||||||
"standard:fix": "./node_modules/.bin/standard --fix ./src",
|
"standard:fix": "./node_modules/.bin/standard --fix ./src",
|
||||||
"mocha": "./node_modules/.bin/mocha",
|
"mocha": "./node_modules/.bin/mocha",
|
||||||
"test": "yarn run standard:check && yarn run license:check && yarn run mocha",
|
"test": "yarn run standard:check && yarn run license:check && yarn run mocha",
|
||||||
"proxy": "NODE_ENV=production node ./src/proxy/",
|
|
||||||
"proxy:dev": "NODE_ENV=development ./node_modules/.bin/nodemon ./src/proxy/",
|
|
||||||
"prepare": "husky install"
|
"prepare": "husky install"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -1,337 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 Yarmo Mackenbach
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
const router = require('express').Router()
|
|
||||||
const dns = require('dns')
|
|
||||||
const axios = require('axios')
|
|
||||||
const validUrl = require('valid-url')
|
|
||||||
const jsdom = require('jsdom')
|
|
||||||
const { client, xml } = require('@xmpp/client')
|
|
||||||
const debug = require('@xmpp/debug')
|
|
||||||
const irc = require('irc-upd')
|
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
const xmppService = process.env.XMPP_SERVICE || null
|
|
||||||
const xmppUsername = process.env.XMPP_USERNAME || null
|
|
||||||
const xmppPassword = process.env.XMPP_PASSWORD || null
|
|
||||||
const twitterBearerToken = process.env.TWITTER_BEARER_TOKEN || null
|
|
||||||
const matrixInstance = process.env.MATRIX_INSTANCE || null
|
|
||||||
const matrixAccessToken = process.env.MATRIX_ACCESS_TOKEN || null
|
|
||||||
const ircNick = process.env.IRC_NICK || null
|
|
||||||
|
|
||||||
let xmpp = null
|
|
||||||
let iqCaller = null
|
|
||||||
let xmppEnabled = true
|
|
||||||
let twitterEnabled = false
|
|
||||||
let matrixEnabled = false
|
|
||||||
let ircEnabled = false
|
|
||||||
|
|
||||||
if (!xmppService || !xmppUsername || !xmppPassword) {
|
|
||||||
xmppEnabled = false
|
|
||||||
}
|
|
||||||
if (twitterBearerToken) {
|
|
||||||
twitterEnabled = true
|
|
||||||
}
|
|
||||||
if (matrixInstance && matrixAccessToken) {
|
|
||||||
matrixEnabled = true
|
|
||||||
}
|
|
||||||
if (ircNick) {
|
|
||||||
ircEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const xmppStart = async (xmppService, xmppUsername, xmppPassword) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const xmpp = client({
|
|
||||||
service: xmppService,
|
|
||||||
username: xmppUsername,
|
|
||||||
password: xmppPassword
|
|
||||||
})
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
debug(xmpp, true)
|
|
||||||
}
|
|
||||||
const { iqCaller } = xmpp
|
|
||||||
xmpp.start()
|
|
||||||
xmpp.on('online', (address) => {
|
|
||||||
console.log('online', address.toString())
|
|
||||||
resolve({ xmpp: xmpp, iqCaller: iqCaller })
|
|
||||||
})
|
|
||||||
xmpp.on('error', (error) => {
|
|
||||||
reject(error)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
router.get('/', async (req, res) => {
|
|
||||||
res.status(200).json({
|
|
||||||
message:
|
|
||||||
'Available endpoints: /json/:url, /text/:url, /dns/:hostname, /xmpp/:xmppid, /twitter/:tweetid, /matrix/:roomid/:eventid, /irc/:ircserver/:ircnick'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.param('url', async (req, res, next, url) => {
|
|
||||||
req.params.url = decodeURI(url)
|
|
||||||
|
|
||||||
if (!validUrl.isUri(req.params.url)) {
|
|
||||||
return res.status(400).send({ message: 'URL provided was not valid' })
|
|
||||||
}
|
|
||||||
|
|
||||||
next()
|
|
||||||
})
|
|
||||||
|
|
||||||
router.param('xmppid', async (req, res, next, xmppid) => {
|
|
||||||
req.params.xmppid = xmppid
|
|
||||||
|
|
||||||
if (/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,})+$/.test(req.params.xmppid)) {
|
|
||||||
next()
|
|
||||||
} else {
|
|
||||||
return res.status(400).json({ message: 'XMPP_ID was not valid' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
router.param('xmppdata', async (req, res, next, xmppdata) => {
|
|
||||||
req.params.xmppdata = xmppdata.toUpperCase()
|
|
||||||
|
|
||||||
const allowedData = [
|
|
||||||
'FN',
|
|
||||||
'NUMBER',
|
|
||||||
'USERID',
|
|
||||||
'URL',
|
|
||||||
'BDAY',
|
|
||||||
'NICKNAME',
|
|
||||||
'NOTE',
|
|
||||||
'DESC'
|
|
||||||
]
|
|
||||||
|
|
||||||
if (!allowedData.includes(req.params.xmppdata)) {
|
|
||||||
return res.status(400).json({
|
|
||||||
message:
|
|
||||||
'Allowed data are: FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
next()
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/json/:url', (req, res) => {
|
|
||||||
axios.get(req.params.url,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
return result.data
|
|
||||||
})
|
|
||||||
.then(async (result) => {
|
|
||||||
return res.status(200).json({ url: req.params.url, content: result })
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
return res.status(400).send({ error: e })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/text/:url', (req, res) => {
|
|
||||||
axios.get(req.params.url,
|
|
||||||
{
|
|
||||||
responseType: 'text'
|
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
return result.data
|
|
||||||
})
|
|
||||||
.then(async (result) => {
|
|
||||||
return res.status(200).json({ url: req.params.url, content: result })
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
return res.status(400).send({ error: e })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/dns/:hostname', async (req, res) => {
|
|
||||||
dns.resolveTxt(req.params.hostname, (err, records) => {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(err)
|
|
||||||
}
|
|
||||||
const out = {
|
|
||||||
hostname: req.params.hostname,
|
|
||||||
records: {
|
|
||||||
txt: records
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res.status(200).json(out)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/xmpp/:xmppid', async (req, res) => {
|
|
||||||
return res
|
|
||||||
.status(400)
|
|
||||||
.json(
|
|
||||||
'Data request parameter missing (FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC)'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/xmpp/:xmppid/:xmppdata', async (req, res) => {
|
|
||||||
if (!xmppEnabled) {
|
|
||||||
return res.status(500).json('XMPP not enabled on server')
|
|
||||||
}
|
|
||||||
if (!xmpp) {
|
|
||||||
const xmppStartRes = await xmppStart(
|
|
||||||
xmppService,
|
|
||||||
xmppUsername,
|
|
||||||
xmppPassword
|
|
||||||
)
|
|
||||||
xmpp = xmppStartRes.xmpp
|
|
||||||
iqCaller = xmppStartRes.iqCaller
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await iqCaller.request(
|
|
||||||
xml(
|
|
||||||
'iq',
|
|
||||||
{ type: 'get', to: req.params.xmppid },
|
|
||||||
xml('vCard', 'vcard-temp')
|
|
||||||
),
|
|
||||||
30 * 1000
|
|
||||||
)
|
|
||||||
|
|
||||||
const vcardRow = response.getChild('vCard', 'vcard-temp').toString()
|
|
||||||
|
|
||||||
const dom = new jsdom.JSDOM(vcardRow)
|
|
||||||
|
|
||||||
try {
|
|
||||||
let vcard
|
|
||||||
|
|
||||||
switch (req.params.xmppdata.toLowerCase()) {
|
|
||||||
case 'desc':
|
|
||||||
case 'note':
|
|
||||||
vcard = dom.window.document.querySelector('note text')
|
|
||||||
if (!vcard) {
|
|
||||||
vcard = dom.window.document.querySelector('DESC')
|
|
||||||
}
|
|
||||||
if (vcard) {
|
|
||||||
vcard = vcard.textContent
|
|
||||||
} else {
|
|
||||||
throw new Error('No DESC or NOTE field found in vCard')
|
|
||||||
}
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
|
||||||
vcard = dom.window.document.querySelector(req.params.xmppdata)
|
|
||||||
.textContent
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return res.status(200).json(vcard)
|
|
||||||
} catch (error) {
|
|
||||||
return res
|
|
||||||
.status(400)
|
|
||||||
.json({ message: 'Request could not be fulfilled', error: error })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/twitter/:tweetid', async (req, res) => {
|
|
||||||
if (!twitterEnabled) {
|
|
||||||
return res.status(500).json('Twitter not enabled on server')
|
|
||||||
}
|
|
||||||
|
|
||||||
axios.get(
|
|
||||||
`https://api.twitter.com/1.1/statuses/show.json?id=${req.params.tweetid}`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
Authorization: `Bearer ${twitterBearerToken}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(data => {
|
|
||||||
return data.data
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).json({ data: data, message: 'Success', error: {} })
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
return res.status(error.statusCode || 400).json({
|
|
||||||
data: [],
|
|
||||||
message: 'Request could not be fulfilled',
|
|
||||||
error: error
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/matrix/:matrixroomid/:matrixeventid', async (req, res) => {
|
|
||||||
if (!matrixEnabled) {
|
|
||||||
return res.status(500).json('Matrix not enabled on server')
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = `https://${matrixInstance}/_matrix/client/r0/rooms/${req.params.matrixroomid}/event/${req.params.matrixeventid}?access_token=${matrixAccessToken}`
|
|
||||||
|
|
||||||
axios.get(url,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
return data.data
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).json({ data: data, message: 'Success', error: {} })
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
return res.status(error.statusCode || 400).json({
|
|
||||||
data: [],
|
|
||||||
message: 'Request could not be fulfilled',
|
|
||||||
error: error
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/get/irc/:ircserver/:ircnick', async (req, res) => {
|
|
||||||
if (!ircEnabled) {
|
|
||||||
return res.status(500).json('IRC not enabled on server')
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const client = new irc.Client(req.params.ircserver, ircNick, {
|
|
||||||
port: 6697,
|
|
||||||
secure: true,
|
|
||||||
channels: []
|
|
||||||
})
|
|
||||||
const reKey = /[a-zA-Z0-9\-_]+\s+:\s(openpgp4fpr:.*)/
|
|
||||||
const reEnd = /End\sof\s.*\staxonomy./
|
|
||||||
const keys = []
|
|
||||||
|
|
||||||
client.addListener('registered', (message) => {
|
|
||||||
client.send(`PRIVMSG NickServ :TAXONOMY ${req.params.ircnick}`)
|
|
||||||
})
|
|
||||||
client.addListener('notice', (nick, to, text, message) => {
|
|
||||||
if (reKey.test(text)) {
|
|
||||||
const match = text.match(reKey)
|
|
||||||
keys.push(match[1])
|
|
||||||
}
|
|
||||||
if (reEnd.test(text)) {
|
|
||||||
client.disconnect()
|
|
||||||
return res
|
|
||||||
.status(200)
|
|
||||||
.json({ data: keys, message: 'Success', error: {} })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
return res.status(400).json({
|
|
||||||
data: [],
|
|
||||||
message: 'Request could not be fulfilled',
|
|
||||||
error: error
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = router
|
|
|
@ -1,274 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 Yarmo Mackenbach
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
const router = require('express').Router()
|
|
||||||
const { query, validationResult } = require('express-validator')
|
|
||||||
const fetcher = require('../../../fetcher')
|
|
||||||
const E = require('../../../enums')
|
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
const opts = {
|
|
||||||
claims: {
|
|
||||||
activitypub: {
|
|
||||||
url: process.env.ACTIVITYPUB_URL || null,
|
|
||||||
privateKey: process.env.ACTIVITYPUB_PRIVATE_KEY || null
|
|
||||||
},
|
|
||||||
irc: {
|
|
||||||
nick: process.env.IRC_NICK || null
|
|
||||||
},
|
|
||||||
matrix: {
|
|
||||||
instance: process.env.MATRIX_INSTANCE || null,
|
|
||||||
accessToken: process.env.MATRIX_ACCESS_TOKEN || null
|
|
||||||
},
|
|
||||||
telegram: {
|
|
||||||
token: process.env.TELEGRAM_TOKEN || null
|
|
||||||
},
|
|
||||||
twitter: {
|
|
||||||
bearerToken: process.env.TWITTER_BEARER_TOKEN || null
|
|
||||||
},
|
|
||||||
xmpp: {
|
|
||||||
service: process.env.XMPP_SERVICE || null,
|
|
||||||
username: process.env.XMPP_USERNAME || null,
|
|
||||||
password: process.env.XMPP_PASSWORD || null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Root route
|
|
||||||
router.get('/', async (req, res) => {
|
|
||||||
return res.status(400).json({ errors: 'Invalid endpoint' })
|
|
||||||
})
|
|
||||||
|
|
||||||
// HTTP route
|
|
||||||
router.get(
|
|
||||||
'/get/http',
|
|
||||||
query('url').isURL(),
|
|
||||||
query('format').isIn([E.ProofFormat.JSON, E.ProofFormat.TEXT]),
|
|
||||||
(req, res) => {
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.http
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((result) => {
|
|
||||||
switch (req.query.format) {
|
|
||||||
case E.ProofFormat.JSON:
|
|
||||||
return res.status(200).json(result)
|
|
||||||
|
|
||||||
case E.ProofFormat.TEXT:
|
|
||||||
return res.status(200).send(result)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// DNS route
|
|
||||||
router.get('/get/dns', query('domain').isFQDN(), (req, res) => {
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.dns
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// XMPP route
|
|
||||||
router.get(
|
|
||||||
'/get/xmpp',
|
|
||||||
query('id').isEmail(),
|
|
||||||
query('field').isIn([
|
|
||||||
'fn',
|
|
||||||
'number',
|
|
||||||
'userid',
|
|
||||||
'url',
|
|
||||||
'bday',
|
|
||||||
'nickname',
|
|
||||||
'note',
|
|
||||||
'desc'
|
|
||||||
]),
|
|
||||||
async (req, res) => {
|
|
||||||
if (
|
|
||||||
!opts.claims.xmpp.service ||
|
|
||||||
!opts.claims.xmpp.username ||
|
|
||||||
!opts.claims.xmpp.password
|
|
||||||
) {
|
|
||||||
return res.status(501).json({ errors: 'XMPP not enabled on server' })
|
|
||||||
}
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.xmpp
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Twitter route
|
|
||||||
router.get('/get/twitter', query('tweetId').isInt(), async (req, res) => {
|
|
||||||
if (!opts.claims.twitter.bearerToken) {
|
|
||||||
return res.status(501).json({ errors: 'Twitter not enabled on server' })
|
|
||||||
}
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.twitter
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Matrix route
|
|
||||||
router.get(
|
|
||||||
'/get/matrix',
|
|
||||||
query('roomId').isString(),
|
|
||||||
query('eventId').isString(),
|
|
||||||
async (req, res) => {
|
|
||||||
if (!opts.claims.matrix.instance || !opts.claims.matrix.accessToken) {
|
|
||||||
return res.status(501).json({ errors: 'Matrix not enabled on server' })
|
|
||||||
}
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.matrix
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Telegram route
|
|
||||||
router.get(
|
|
||||||
'/get/telegram',
|
|
||||||
query('user').isString(),
|
|
||||||
query('chat').isString(),
|
|
||||||
async (req, res) => {
|
|
||||||
if (!opts.claims.telegram.token) {
|
|
||||||
return res.status(501).json({ errors: 'Telegram not enabled on server' })
|
|
||||||
}
|
|
||||||
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.telegram
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// IRC route
|
|
||||||
router.get('/get/irc', query('nick').isString(), async (req, res) => {
|
|
||||||
if (!opts.claims.irc.nick) {
|
|
||||||
return res.status(501).json({ errors: 'IRC not enabled on server' })
|
|
||||||
}
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.irc
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Gitlab route
|
|
||||||
router.get(
|
|
||||||
'/get/gitlab',
|
|
||||||
query('domain').isFQDN(),
|
|
||||||
query('username').isString(),
|
|
||||||
async (req, res) => {
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.http
|
|
||||||
.fn({
|
|
||||||
url: `https://${req.query.domain}/api/v4/projects/${req.query.username}%2Fgitlab_proof`,
|
|
||||||
format: 'json'
|
|
||||||
}, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ActivityPub route
|
|
||||||
router.get(
|
|
||||||
'/get/activitypub',
|
|
||||||
query('url').isURL(),
|
|
||||||
async (req, res) => {
|
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher.activitypub
|
|
||||||
.fn(req.query, opts)
|
|
||||||
.then((data) => {
|
|
||||||
return res.status(200).send(data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return res.status(400).json({ errors: err.message ? err.message : err })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
module.exports = router
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 Yarmo Mackenbach
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
Copyright 2020 Yarmo Mackenbach
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
const express = require('express')
|
|
||||||
const app = express()
|
|
||||||
const cors = require('cors')
|
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
app.use(cors())
|
|
||||||
app.set('port', process.env.PORT || 3000)
|
|
||||||
|
|
||||||
app.use('/api/1', require('./api/v1/'))
|
|
||||||
app.use('/api/2', require('./api/v2/'))
|
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
|
||||||
return res.status(200).json({ message: 'Available endpoints: /api' })
|
|
||||||
})
|
|
||||||
app.get('/api', (req, res) => {
|
|
||||||
return res
|
|
||||||
.status(200)
|
|
||||||
.json({ message: 'Available API versions: /api/1, /api/2' })
|
|
||||||
})
|
|
||||||
app.all('*', (req, res) => {
|
|
||||||
return res.status(404).json({ message: 'API endpoint not found' })
|
|
||||||
})
|
|
||||||
|
|
||||||
app.listen(app.get('port'), () => {
|
|
||||||
console.log(`Node server listening at http://localhost:${app.get('port')}`)
|
|
||||||
})
|
|
Loading…
Reference in a new issue