mirror of https://github.com/tootsuite/mastodon
Merge 162506a6bb into 3c7f3b190c
commit
021547c5fc
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import fs from 'node:fs';
|
||||
import http from 'node:http';
|
||||
import net from 'node:net';
|
||||
import path from 'node:path';
|
||||
import url from 'node:url';
|
||||
|
||||
|
|
@ -9,6 +10,7 @@ import cors from 'cors';
|
|||
import dotenv from 'dotenv';
|
||||
import express from 'express';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import proxyaddr from 'proxy-addr';
|
||||
import { WebSocketServer } from 'ws';
|
||||
|
||||
import * as Database from './database.js';
|
||||
|
|
@ -146,8 +148,13 @@ const startServer = async () => {
|
|||
});
|
||||
|
||||
const app = express();
|
||||
const trustProxy = proxyaddr.compile(
|
||||
process.env.TRUSTED_PROXY_IP ?
|
||||
process.env.TRUSTED_PROXY_IP.split(/(?:\s*,\s*|\s+)/) :
|
||||
['loopback', 'uniquelocal']
|
||||
);
|
||||
|
||||
app.set('trust proxy', process.env.TRUSTED_PROXY_IP ? process.env.TRUSTED_PROXY_IP.split(/(?:\s*,\s*|\s+)/) : 'loopback,uniquelocal');
|
||||
app.set('trust proxy', trustProxy);
|
||||
|
||||
app.use(httpLogger);
|
||||
app.use(cors());
|
||||
|
|
@ -161,6 +168,15 @@ const startServer = async () => {
|
|||
// logger. This decorates the `request` object.
|
||||
attachWebsocketHttpLogger(request);
|
||||
|
||||
// Define the `request.ip` property
|
||||
Object.defineProperty(request, 'ip', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
return proxyaddr(this, trustProxy);
|
||||
}
|
||||
});
|
||||
|
||||
request.log.info("HTTP Upgrade Requested");
|
||||
|
||||
/** @param {Error} err */
|
||||
|
|
@ -349,28 +365,53 @@ const startServer = async () => {
|
|||
const isInScope = (req, necessaryScopes) =>
|
||||
req.scopes.some(scope => necessaryScopes.includes(scope));
|
||||
|
||||
const ACCESS_TOKEN_UPDATE_FREQUENCY = 24 * 60 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Fetches the account from the access token, updating access token usage if necessary.
|
||||
* `req.ip` comes from `proxyaddr`
|
||||
* @param {string} token
|
||||
* @param {any} req
|
||||
* @param {http.IncomingMessage & { ip: string } & ResolvedAccount} req
|
||||
* @returns {Promise<ResolvedAccount>}
|
||||
*/
|
||||
const accountFromToken = async (token, req) => {
|
||||
const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token]);
|
||||
const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes, oauth_access_tokens.last_used_at FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
if (result.rows.length === 0 || result.rows.length > 1) {
|
||||
throw new AuthenticationError('Invalid access token');
|
||||
}
|
||||
|
||||
req.accessTokenId = result.rows[0].id;
|
||||
req.scopes = result.rows[0].scopes.split(' ');
|
||||
req.accountId = result.rows[0].account_id;
|
||||
req.chosenLanguages = result.rows[0].chosen_languages;
|
||||
const accessToken = result.rows[0];
|
||||
|
||||
// Track the usage of the access token if necessary:
|
||||
// This is the same code as: app/controllers/concerns/api/access_token_tracking_concern.rb
|
||||
if (accessToken.last_used_at === null || accessToken.last_used_at < Date.now() - ACCESS_TOKEN_UPDATE_FREQUENCY) {
|
||||
let query, variables = [];
|
||||
if (req.ip && net.isIP(req.ip)) {
|
||||
query = 'UPDATE "oauth_access_tokens" SET "last_used_at" = $2, "last_used_ip" = $3 WHERE "oauth_access_tokens"."id" = $1';
|
||||
variables = [ accessToken.id, new Date(), req.ip ];
|
||||
} else {
|
||||
query = 'UPDATE "oauth_access_tokens" SET "last_used_at" = $2 WHERE "oauth_access_tokens"."id" = $1';
|
||||
variables = [ accessToken.id, new Date() ];
|
||||
}
|
||||
|
||||
try {
|
||||
await pgPool.query(query, variables);
|
||||
} catch (err) {
|
||||
req.log.error(err, 'Error updating Access Token usage tracking');
|
||||
}
|
||||
}
|
||||
|
||||
req.accessTokenId = accessToken.id;
|
||||
req.scopes = accessToken.scopes.split(' ');
|
||||
req.accountId = accessToken.account_id;
|
||||
req.chosenLanguages = accessToken.chosen_languages;
|
||||
|
||||
return {
|
||||
accessTokenId: result.rows[0].id,
|
||||
scopes: result.rows[0].scopes.split(' '),
|
||||
accountId: result.rows[0].account_id,
|
||||
chosenLanguages: result.rows[0].chosen_languages,
|
||||
accessTokenId: accessToken.id,
|
||||
scopes: accessToken.scopes.split(' '),
|
||||
accountId: accessToken.account_id,
|
||||
chosenLanguages: accessToken.chosen_languages,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
"pino": "^9.0.0",
|
||||
"pino-http": "^10.0.0",
|
||||
"prom-client": "^15.0.0",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"uuid": "^11.0.0",
|
||||
"ws": "^8.12.1"
|
||||
},
|
||||
|
|
@ -34,11 +35,13 @@
|
|||
"@types/cors": "^2.8.16",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/pg": "^8.6.6",
|
||||
"@types/proxy-addr": "^2.0.3",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/ws": "^8.5.9",
|
||||
"eslint-define-config": "^2.0.0",
|
||||
"pino-pretty": "^11.0.0",
|
||||
"typescript": "^5.0.4"
|
||||
"typescript": "^5.0.4",
|
||||
"wscat": "^6.0.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"bufferutil": "^4.0.7",
|
||||
|
|
|
|||
58
yarn.lock
58
yarn.lock
|
|
@ -3053,6 +3053,7 @@ __metadata:
|
|||
"@types/cors": "npm:^2.8.16"
|
||||
"@types/express": "npm:^4.17.17"
|
||||
"@types/pg": "npm:^8.6.6"
|
||||
"@types/proxy-addr": "npm:^2.0.3"
|
||||
"@types/uuid": "npm:^10.0.0"
|
||||
"@types/ws": "npm:^8.5.9"
|
||||
bufferutil: "npm:^4.0.7"
|
||||
|
|
@ -3068,10 +3069,12 @@ __metadata:
|
|||
pino-http: "npm:^10.0.0"
|
||||
pino-pretty: "npm:^11.0.0"
|
||||
prom-client: "npm:^15.0.0"
|
||||
proxy-addr: "npm:~2.0.7"
|
||||
typescript: "npm:^5.0.4"
|
||||
utf-8-validate: "npm:^6.0.3"
|
||||
uuid: "npm:^11.0.0"
|
||||
ws: "npm:^8.12.1"
|
||||
wscat: "npm:^6.0.1"
|
||||
dependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
|
|
@ -4073,6 +4076,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/proxy-addr@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@types/proxy-addr@npm:2.0.3"
|
||||
dependencies:
|
||||
"@types/node": "npm:*"
|
||||
checksum: 10c0/680f5eeaf434461daf856d694fd6b228c9850f736f377b8fc1d373ba282feca25bc642eeed93f3a9511d9406a9b93014b94c4d7cb8488646482ca0610d931e30
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/punycode@npm:^2.1.0":
|
||||
version: 2.1.4
|
||||
resolution: "@types/punycode@npm:2.1.4"
|
||||
|
|
@ -6402,6 +6414,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:^12.1.0, commander@npm:~12.1.0":
|
||||
version: 12.1.0
|
||||
resolution: "commander@npm:12.1.0"
|
||||
checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:^2.20.0":
|
||||
version: 2.20.3
|
||||
resolution: "commander@npm:2.20.3"
|
||||
|
|
@ -6416,13 +6435,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:~12.1.0":
|
||||
version: 12.1.0
|
||||
resolution: "commander@npm:12.1.0"
|
||||
checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"comment-parser@npm:1.4.1":
|
||||
version: 1.4.1
|
||||
resolution: "comment-parser@npm:1.4.1"
|
||||
|
|
@ -12390,6 +12402,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mute-stream@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "mute-stream@npm:2.0.0"
|
||||
checksum: 10c0/2cf48a2087175c60c8dcdbc619908b49c07f7adcfc37d29236b0c5c612d6204f789104c98cc44d38acab7b3c96f4a3ec2cfdc4934d0738d876dbefa2a12c69f4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nan@npm:^2.12.1":
|
||||
version: 2.17.0
|
||||
resolution: "nan@npm:2.17.0"
|
||||
|
|
@ -15060,6 +15079,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"read@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "read@npm:4.0.0"
|
||||
dependencies:
|
||||
mute-stream: "npm:^2.0.0"
|
||||
checksum: 10c0/448dd2cb8163fa7004dbe9e7fc9b0814cedd55028e2d45fbebd774f6b05e3ac046b092f3910a4eff942471187afa0b56b5db6caf2cd230d264d8d8fe22f9af6f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6":
|
||||
version: 2.3.8
|
||||
resolution: "readable-stream@npm:2.3.8"
|
||||
|
|
@ -18777,7 +18805,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.18.0":
|
||||
"ws@npm:^8.0.0, ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.18.0":
|
||||
version: 8.18.0
|
||||
resolution: "ws@npm:8.18.0"
|
||||
peerDependencies:
|
||||
|
|
@ -18792,6 +18820,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"wscat@npm:^6.0.1":
|
||||
version: 6.0.1
|
||||
resolution: "wscat@npm:6.0.1"
|
||||
dependencies:
|
||||
commander: "npm:^12.1.0"
|
||||
https-proxy-agent: "npm:^7.0.5"
|
||||
read: "npm:^4.0.0"
|
||||
ws: "npm:^8.0.0"
|
||||
bin:
|
||||
wscat: bin/wscat
|
||||
checksum: 10c0/8245b6cdebb6bde8bc6bf647991d289107bdbda24f51cf820683f40a06b72226e606fbc8d263e4812018928315200377e615035918399bdcaca8b0b0182ecbd1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xml-name-validator@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "xml-name-validator@npm:4.0.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue