Cleanup
This commit is contained in:
parent
4841823d67
commit
b075e25330
|
@ -10,15 +10,9 @@ exports.getJson = getJson;
|
||||||
exports.postJson = postJson;
|
exports.postJson = postJson;
|
||||||
|
|
||||||
function getJson(url, options, cb) {
|
function getJson(url, options, cb) {
|
||||||
const defaultOptions = {
|
options = Object.assign({}, { method: 'GET' }, options);
|
||||||
method: 'GET',
|
|
||||||
};
|
|
||||||
|
|
||||||
options = Object.assign({}, defaultOptions, options);
|
return _makeRequest(url, options, (err, body, res) => {
|
||||||
|
|
||||||
// :TODO: signing -- DRY this.
|
|
||||||
|
|
||||||
_makeRequest(url, options, (err, body, res) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
|
@ -39,26 +33,28 @@ function postJson(url, json, options, cb) {
|
||||||
json = JSON.stringify(json);
|
json = JSON.stringify(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
// :TODO: DRY this method with _makeRequest()
|
options = Object.assign({}, { method: 'POST', body: json }, options);
|
||||||
|
if (
|
||||||
|
!options.headers ||
|
||||||
|
!Object.keys(options.headers).find(h => h.toLowerCase() === 'content-type')
|
||||||
|
) {
|
||||||
|
options.headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
|
||||||
const defaultOptions = {
|
return _makeRequest(url, options, cb);
|
||||||
method: 'POST',
|
}
|
||||||
body: json,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
options = Object.assign({}, defaultOptions, options);
|
function _makeRequest(url, options, cb) {
|
||||||
|
if (options.body) {
|
||||||
|
options.headers['Content-Length'] = options.body.length;
|
||||||
|
|
||||||
if (options?.sign?.headers?.includes('digest')) {
|
if (options?.sign?.headers?.includes('digest')) {
|
||||||
options.headers['Digest'] = `SHA-256=${crypto
|
options.headers['Digest'] = `SHA-256=${crypto
|
||||||
.createHash('sha256')
|
.createHash('sha256')
|
||||||
.update(json)
|
.update(options.body)
|
||||||
.digest('base64')}`;
|
.digest('base64')}`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
options.headers['Content-Length'] = json.length;
|
|
||||||
|
|
||||||
const req = https.request(url, options, res => {
|
const req = https.request(url, options, res => {
|
||||||
let body = [];
|
let body = [];
|
||||||
|
@ -73,9 +69,7 @@ function postJson(url, json, options, cb) {
|
||||||
return cb(
|
return cb(
|
||||||
Errors.HttpError(
|
Errors.HttpError(
|
||||||
`HTTP error ${res.statusCode}: ${truncate(body, { length: 128 })}`
|
`HTTP error ${res.statusCode}: ${truncate(body, { length: 128 })}`
|
||||||
),
|
)
|
||||||
body,
|
|
||||||
res
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,52 +95,5 @@ function postJson(url, json, options, cb) {
|
||||||
return cb(Errors.Timeout('Timeout making HTTP request'));
|
return cb(Errors.Timeout('Timeout making HTTP request'));
|
||||||
});
|
});
|
||||||
|
|
||||||
req.write(json);
|
|
||||||
req.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
function _makeRequest(url, options, cb) {
|
|
||||||
if (options.body && options?.sign?.headers?.includes('digest')) {
|
|
||||||
options.headers['Digest'] = `SHA-256=${crypto
|
|
||||||
.createHash('sha256')
|
|
||||||
.update(options.body)
|
|
||||||
.digest('base64')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const req = https.request(url, options, res => {
|
|
||||||
let body = [];
|
|
||||||
res.on('data', d => {
|
|
||||||
body.push(d);
|
|
||||||
});
|
|
||||||
|
|
||||||
res.on('end', () => {
|
|
||||||
body = Buffer.concat(body).toString();
|
|
||||||
|
|
||||||
if (res.statusCode < 200 || res.statusCode > 299) {
|
|
||||||
return cb(Errors.HttpError(`HTTP error ${res.statusCode}: ${body}`));
|
|
||||||
}
|
|
||||||
|
|
||||||
return cb(null, body, res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isObject(options.sign)) {
|
|
||||||
try {
|
|
||||||
httpSignature.sign(req, options.sign);
|
|
||||||
} catch (e) {
|
|
||||||
req.destroy();
|
|
||||||
return cb(Errors.Invalid(`Invalid signing material: ${e}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
req.on('error', err => {
|
|
||||||
return cb(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('timeout', () => {
|
|
||||||
req.destroy();
|
|
||||||
return cb(Errors.Timeout('Timeout making HTTP request'));
|
|
||||||
});
|
|
||||||
|
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,10 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
this.webServer.addRoute({
|
this.webServer.addRoute({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: /^\/_enig\/ap\/users\/.+\/outbox$/,
|
path: /^\/_enig\/ap\/users\/.+\/outbox$/,
|
||||||
handler: this._outboxGetHandler.bind(this),
|
handler: this._enforceSigningPolicy.bind(
|
||||||
|
this,
|
||||||
|
this._outboxGetHandler.bind(this)
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.webServer.addRoute({
|
this.webServer.addRoute({
|
||||||
|
@ -72,6 +75,16 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
return cb(null);
|
return cb(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_enforceSigningPolicy(req, resp, next) {
|
||||||
|
// the request must be signed, and the signature must be valid
|
||||||
|
const signature = this._parseAndValidateSignature(req);
|
||||||
|
if (!signature) {
|
||||||
|
return this.webServer.accessDenied(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(req, resp);
|
||||||
|
}
|
||||||
|
|
||||||
_selfUrlRequestHandler(req, resp) {
|
_selfUrlRequestHandler(req, resp) {
|
||||||
this.log.trace({ url: req.url }, 'Request for "self"');
|
this.log.trace({ url: req.url }, 'Request for "self"');
|
||||||
|
|
||||||
|
@ -295,9 +308,8 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
return keyId.endsWith('#main-key');
|
return keyId.endsWith('#main-key');
|
||||||
}
|
}
|
||||||
|
|
||||||
_inboxFollowRequestHandler(activity, user, resp) {
|
_inboxFollowRequestHandler(activity, remoteActor, user, resp) {
|
||||||
this.log.debug({ user: user, type: activity.type }, 'Got a follow request!');
|
this.log.debug({ user_id: user.userId, actor: activity.actor }, 'Follow request');
|
||||||
// :TODO: return OK and kick off a async job of persisting and sending and 'Accepted'
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the user blindly accepts Followers, we can persist
|
// If the user blindly accepts Followers, we can persist
|
||||||
|
@ -305,10 +317,11 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
// request for the user to review and decide what to do with
|
// request for the user to review and decide what to do with
|
||||||
// at a later time.
|
// at a later time.
|
||||||
//
|
//
|
||||||
// :TODO: Implement the queue
|
|
||||||
const activityPubSettings = ActivityPubSettings.fromUser(user);
|
const activityPubSettings = ActivityPubSettings.fromUser(user);
|
||||||
if (!activityPubSettings.manuallyApproveFollowers) {
|
if (!activityPubSettings.manuallyApproveFollowers) {
|
||||||
this._recordAcceptedFollowRequest(user, activity.actor, activity);
|
this._recordAcceptedFollowRequest(user, remoteActor, activity);
|
||||||
|
} else {
|
||||||
|
// :TODO: queue the request
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.writeHead(200, { 'Content-Type': 'text/html' });
|
resp.writeHead(200, { 'Content-Type': 'text/html' });
|
||||||
|
@ -358,7 +371,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
return this.webServer.accessDenied(resp);
|
return this.webServer.accessDenied(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return activityHandler(activity, user, resp);
|
return activityHandler(activity, actor, user, resp);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue