Return a outbox WIP
This commit is contained in:
parent
157b90687c
commit
5e5c9236ec
|
@ -1,18 +1,21 @@
|
||||||
const { isString, isObject } = require('lodash');
|
|
||||||
const { v4: UUIDv4 } = require('uuid');
|
|
||||||
const {
|
const {
|
||||||
ActivityStreamsContext,
|
ActivityStreamsContext,
|
||||||
messageBodyToHtml,
|
messageBodyToHtml,
|
||||||
selfUrl,
|
selfUrl,
|
||||||
} = require('../activitypub/util');
|
makeUserUrl,
|
||||||
const { Errors } = require('../enig_error');
|
} = require('./util');
|
||||||
const User = require('../user');
|
const User = require('../user');
|
||||||
const Actor = require('../activitypub/actor');
|
const Actor = require('./actor');
|
||||||
|
const { Errors } = require('../enig_error');
|
||||||
const { getISOTimestampString } = require('../database');
|
const { getISOTimestampString } = require('../database');
|
||||||
const UserProps = require('../user_property');
|
const UserProps = require('../user_property');
|
||||||
const { postJson } = require('../http_util');
|
const { postJson } = require('../http_util');
|
||||||
|
const { getOutboxEntries } = require('./db');
|
||||||
|
const { WellKnownLocations } = require('../servers/content/web');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
|
const { isString, isObject } = require('lodash');
|
||||||
|
const { v4: UUIDv4 } = require('uuid');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
@ -119,6 +122,7 @@ module.exports = class Activity {
|
||||||
type: 'Note',
|
type: 'Note',
|
||||||
published: getISOTimestampString(message.modTimestamp),
|
published: getISOTimestampString(message.modTimestamp),
|
||||||
attributedTo: localActor.id,
|
attributedTo: localActor.id,
|
||||||
|
audience: [message.isPrivate() ? 'as:Private' : 'as:Public'],
|
||||||
// :TODO: inReplyto if this is a reply; we need this store in message meta.
|
// :TODO: inReplyto if this is a reply; we need this store in message meta.
|
||||||
|
|
||||||
content: messageBodyToHtml(message.message.trim()),
|
content: messageBodyToHtml(message.message.trim()),
|
||||||
|
@ -146,6 +150,37 @@ module.exports = class Activity {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromOutboxEntries(owningUser, webServer, cb) {
|
||||||
|
// :TODO: support paging
|
||||||
|
const getOpts = {
|
||||||
|
create: true, // items marked 'Create'
|
||||||
|
};
|
||||||
|
getOutboxEntries(owningUser, getOpts, (err, entries) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const obj = {
|
||||||
|
'@context': ActivityStreamsContext,
|
||||||
|
// :TODO: makeOutboxUrl() and use elsewhere also
|
||||||
|
id: makeUserUrl(webServer, owningUser, '/ap/users') + '/outbox',
|
||||||
|
type: 'OrderedCollection',
|
||||||
|
totalItems: entries.length,
|
||||||
|
orderedItems: entries.map(e => {
|
||||||
|
return {
|
||||||
|
'@context': ActivityStreamsContext,
|
||||||
|
id: e.activity.id,
|
||||||
|
type: 'Create',
|
||||||
|
actor: e.activity.actor,
|
||||||
|
object: e.activity.object,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
return cb(null, new Activity(obj));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
sendTo(actorUrl, fromUser, webServer, cb) {
|
sendTo(actorUrl, fromUser, webServer, cb) {
|
||||||
const privateKey = fromUser.getProperty(UserProps.PrivateKeyMain);
|
const privateKey = fromUser.getProperty(UserProps.PrivateKeyMain);
|
||||||
if (_.isEmpty(privateKey)) {
|
if (_.isEmpty(privateKey)) {
|
||||||
|
@ -173,7 +208,10 @@ module.exports = class Activity {
|
||||||
return postJson(actorUrl, activityJson, reqOpts, cb);
|
return postJson(actorUrl, activityJson, reqOpts, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _makeFullId(webServer, prefix, uuid = '') {
|
static _makeFullId(webServer, prefix) {
|
||||||
return webServer.buildUrl(`/${prefix}/${uuid || UUIDv4()}`);
|
// e.g. http://some.host/_enig/ap/note/bf81a22e-cb3e-41c8-b114-21f375b61124
|
||||||
|
return webServer.buildUrl(
|
||||||
|
WellKnownLocations.Internal + `/ap/${prefix}/${UUIDv4()}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,17 +1,57 @@
|
||||||
const apDb = require('../database').dbs.activitypub;
|
const apDb = require('../database').dbs.activitypub;
|
||||||
|
|
||||||
exports.persistToOutbox = persistToOutbox;
|
exports.persistToOutbox = persistToOutbox;
|
||||||
|
exports.getOutboxEntries = getOutboxEntries;
|
||||||
|
|
||||||
function persistToOutbox(activity, userId, messageId, cb) {
|
function persistToOutbox(activity, fromUser, message, cb) {
|
||||||
const activityJson = JSON.stringify(activity);
|
const activityJson = JSON.stringify(activity);
|
||||||
|
|
||||||
apDb.run(
|
apDb.run(
|
||||||
`INSERT INTO activitypub_outbox (activity_id, user_id, message_id, activity_json)
|
`INSERT INTO outbox (activity_id, user_id, message_id, activity_json, published_timestamp)
|
||||||
VALUES (?, ?, ?, ?);`,
|
VALUES (?, ?, ?, ?, ?);`,
|
||||||
[activity.id, userId, messageId, activityJson],
|
[
|
||||||
|
activity.id,
|
||||||
|
fromUser.userId,
|
||||||
|
message.messageId,
|
||||||
|
activityJson,
|
||||||
|
activity.object.published,
|
||||||
|
],
|
||||||
function res(err) {
|
function res(err) {
|
||||||
// non-arrow for 'this' scope
|
// non-arrow for 'this' scope
|
||||||
return cb(err, this.lastID);
|
return cb(err, this.lastID);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOutboxEntries(owningUser, options, cb) {
|
||||||
|
apDb.all(
|
||||||
|
`SELECT id, activity_id, message_id, activity_json, published_timestamp
|
||||||
|
FROM outbox
|
||||||
|
WHERE user_id = ? AND json_extract(activity_json, '$.type') = "Create";`,
|
||||||
|
[owningUser.userId],
|
||||||
|
(err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const entries = rows.map(r => {
|
||||||
|
let parsed;
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(r.activity_json);
|
||||||
|
} catch (e) {
|
||||||
|
return cb(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: r.id,
|
||||||
|
activityId: r.activity_id,
|
||||||
|
messageId: r.message_id,
|
||||||
|
activity: parsed,
|
||||||
|
published: r.published_timestamp,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return cb(null, entries);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const UserProps = require('./user_property');
|
const UserProps = require('../user_property');
|
||||||
|
|
||||||
module.exports = class ActivityPubSettings {
|
module.exports = class ActivityPubSettings {
|
||||||
constructor(obj) {
|
constructor(obj) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const { WellKnownLocations } = require('./servers/content/web');
|
const { WellKnownLocations } = require('../servers/content/web');
|
||||||
const User = require('./user');
|
const User = require('../user');
|
||||||
const { Errors, ErrorReasons } = require('./enig_error');
|
const { Errors, ErrorReasons } = require('../enig_error');
|
||||||
const UserProps = require('./user_property');
|
const UserProps = require('../user_property');
|
||||||
const ActivityPubSettings = require('./activitypub/settings');
|
const ActivityPubSettings = require('./settings');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
|
@ -502,26 +502,33 @@ dbs.message.run(
|
||||||
return cb(null);
|
return cb(null);
|
||||||
},
|
},
|
||||||
activitypub: cb => {
|
activitypub: cb => {
|
||||||
|
// private INTEGER NOT NULL, -- Is this Activity private?
|
||||||
dbs.activitypub.run(
|
dbs.activitypub.run(
|
||||||
`CREATE TABLE IF NOT EXISTS activitypub_outbox (
|
`CREATE TABLE IF NOT EXISTS outbox (
|
||||||
id INTEGER PRIMARY KEY, -- Local ID
|
id INTEGER PRIMARY KEY, -- Local ID
|
||||||
activity_id VARCHAR NOT NULL, -- Fully qualified Activity ID/URL
|
activity_id VARCHAR NOT NULL, -- Fully qualified Activity ID/URL (activity.id)
|
||||||
user_id INTEGER NOT NULL, -- Local user ID
|
user_id INTEGER NOT NULL, -- Local user ID
|
||||||
message_id INTEGER NOT NULL, -- Local message ID
|
message_id INTEGER NOT NULL, -- Local message ID
|
||||||
activity_json VARCHAR NOT NULL, -- Activity in JSON format
|
activity_json VARCHAR NOT NULL, -- Activity in JSON format
|
||||||
|
published_timestamp DATETIME NOT NULL, -- (activity.object.published))
|
||||||
|
|
||||||
UNIQUE(message_id, activity_id)
|
UNIQUE(message_id, activity_id)
|
||||||
);`
|
);`
|
||||||
);
|
);
|
||||||
|
|
||||||
dbs.activitypub.run(
|
dbs.activitypub.run(
|
||||||
`CREATE INDEX IF NOT EXISTS activitypub_outbox_user_id_index0
|
`CREATE INDEX IF NOT EXISTS outbox_user_id_index0
|
||||||
ON activitypub_outbox (user_id);`
|
ON outbox (user_id);`
|
||||||
);
|
);
|
||||||
|
|
||||||
dbs.activitypub.run(
|
dbs.activitypub.run(
|
||||||
`CREATE INDEX IF NOT EXISTS activitypub_outbox_activity_id_index0
|
`CREATE INDEX IF NOT EXISTS outbox_activity_id_index0
|
||||||
ON activitypub_outbox (activity_id);`
|
ON outbox (activity_id);`
|
||||||
|
);
|
||||||
|
|
||||||
|
dbs.activitypub.run(
|
||||||
|
`CREATE INDEX IF NOT EXISTS outbox_activity_json_type_index0
|
||||||
|
ON outbox (json_extract(activity_json, '$.type'));`
|
||||||
);
|
);
|
||||||
|
|
||||||
return cb(null);
|
return cb(null);
|
||||||
|
|
|
@ -82,11 +82,7 @@ exports.getModule = class ActivityPubScannerTosser extends MessageScanTossModule
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
(activity, fromUser, callback) => {
|
(activity, fromUser, callback) => {
|
||||||
persistToOutbox(
|
persistToOutbox(activity, fromUser, message, (err, localId) => {
|
||||||
activity,
|
|
||||||
fromUser.userId,
|
|
||||||
message.messageId,
|
|
||||||
(err, localId) => {
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
this.log.debug(
|
this.log.debug(
|
||||||
{ localId, activityId: activity.id },
|
{ localId, activityId: activity.id },
|
||||||
|
@ -94,8 +90,7 @@ exports.getModule = class ActivityPubScannerTosser extends MessageScanTossModule
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return callback(err, activity);
|
return callback(err, activity);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
},
|
},
|
||||||
(activity, callback) => {
|
(activity, callback) => {
|
||||||
// mark exported
|
// mark exported
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
/* jslint node: true */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const Log = require('../../logger.js').log;
|
const Log = require('../../logger.js').log;
|
||||||
const ServerModule = require('../../server_module.js').ServerModule;
|
const ServerModule = require('../../server_module.js').ServerModule;
|
||||||
|
|
|
@ -4,11 +4,14 @@ const {
|
||||||
getUserProfileTemplatedBody,
|
getUserProfileTemplatedBody,
|
||||||
DefaultProfileTemplate,
|
DefaultProfileTemplate,
|
||||||
accountFromSelfUrl,
|
accountFromSelfUrl,
|
||||||
|
ActivityStreamsContext,
|
||||||
|
makeUserUrl,
|
||||||
} = require('../../../activitypub/util');
|
} = require('../../../activitypub/util');
|
||||||
const Config = require('../../../config').get;
|
const Config = require('../../../config').get;
|
||||||
const Activity = require('../../../activitypub/activity');
|
const Activity = require('../../../activitypub/activity');
|
||||||
const ActivityPubSettings = require('../../../activitypub/settings');
|
const ActivityPubSettings = require('../../../activitypub/settings');
|
||||||
const Actor = require('../../../activitypub/actor');
|
const Actor = require('../../../activitypub/actor');
|
||||||
|
const { getOutboxEntries } = require('../../../activitypub/db');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
@ -22,6 +25,8 @@ exports.moduleInfo = {
|
||||||
packageName: 'codes.l33t.enigma.web.handler.activitypub',
|
packageName: 'codes.l33t.enigma.web.handler.activitypub',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ActivityJsonMime = 'application/activity+json';
|
||||||
|
|
||||||
exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -45,6 +50,12 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
handler: this._inboxPostHandler.bind(this),
|
handler: this._inboxPostHandler.bind(this),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.webServer.addRoute({
|
||||||
|
method: 'GET',
|
||||||
|
path: /^\/_enig\/ap\/users\/.+\/outbox(\?page=true)?$/,
|
||||||
|
handler: this._outboxGetHandler.bind(this),
|
||||||
|
});
|
||||||
|
|
||||||
// :TODO: NYI
|
// :TODO: NYI
|
||||||
// this.webServer.addRoute({
|
// this.webServer.addRoute({
|
||||||
// method: 'GET',
|
// method: 'GET',
|
||||||
|
@ -80,7 +91,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
// Additionally, serve activity JSON if the proper 'Accept' header was sent
|
// Additionally, serve activity JSON if the proper 'Accept' header was sent
|
||||||
const accept = req.headers['accept'].split(',').map(v => v.trim()) || ['*/*'];
|
const accept = req.headers['accept'].split(',').map(v => v.trim()) || ['*/*'];
|
||||||
const headerValues = [
|
const headerValues = [
|
||||||
'application/activity+json',
|
ActivityJsonMime,
|
||||||
'application/ld+json',
|
'application/ld+json',
|
||||||
'application/json',
|
'application/json',
|
||||||
];
|
];
|
||||||
|
@ -96,26 +107,20 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
|
|
||||||
_inboxPostHandler(req, resp) {
|
_inboxPostHandler(req, resp) {
|
||||||
// the request must be signed, and the signature must be valid
|
// the request must be signed, and the signature must be valid
|
||||||
const signature = this._parseSignature(req);
|
const signature = this._parseAndValidateSignature(req);
|
||||||
if (!signature) {
|
if (!signature) {
|
||||||
return this.webServer.resourceNotFound(resp);
|
return this.webServer.accessDenied(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// quick check up front
|
const body = [];
|
||||||
const keyId = signature.keyId;
|
req.on('data', d => {
|
||||||
if (!this._validateKeyId(keyId)) {
|
body.push(d);
|
||||||
return this.webServer.resourceNotFound(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = '';
|
|
||||||
req.on('data', data => {
|
|
||||||
body += data;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on('end', () => {
|
req.on('end', () => {
|
||||||
let activity;
|
let activity;
|
||||||
try {
|
try {
|
||||||
activity = Activity.fromJson(body);
|
activity = Activity.fromJson(Buffer.concat(body).toString());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.log.error(
|
this.log.error(
|
||||||
{ error: e.message, url: req.url, method: req.method },
|
{ error: e.message, url: req.url, method: req.method },
|
||||||
|
@ -125,7 +130,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!activity.isValid()) {
|
if (!activity.isValid()) {
|
||||||
// :TODO: Log me
|
this.log.warn({ activity }, 'Invalid or unsupported Activity');
|
||||||
return this.webServer.webServer.badRequest(resp);
|
return this.webServer.webServer.badRequest(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,19 +153,110 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_parseSignature(req) {
|
// https://docs.gotosocial.org/en/latest/federation/behaviors/outbox/
|
||||||
|
_outboxGetHandler(req, resp) {
|
||||||
|
this.log.trace({ url: req.url }, 'Request for "outbox"');
|
||||||
|
|
||||||
|
// the request must be signed, and the signature must be valid
|
||||||
|
const signature = this._parseAndValidateSignature(req);
|
||||||
|
if (!signature) {
|
||||||
|
return this.webServer.accessDenied(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /_enig/ap/users/SomeName/outbox -> SomeName
|
||||||
|
const url = new URL(req.url, `https://${req.headers.host}`);
|
||||||
|
const m = url.pathname.match(/^\/_enig\/ap\/users\/(.+)\/outbox$/);
|
||||||
|
if (!m || !m[1]) {
|
||||||
|
return this.webServer.resourceNotFound(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountName = m[1];
|
||||||
|
userFromAccount(accountName, (err, user) => {
|
||||||
|
if (err) {
|
||||||
|
this.log.info(
|
||||||
|
{ reason: err.message, accountName: accountName },
|
||||||
|
`No user "${accountName}" for "self"`
|
||||||
|
);
|
||||||
|
return this.webServer.resourceNotFound(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// // we return a OrderedCollection response if this request
|
||||||
|
// // is not explicitly for a page of the collection
|
||||||
|
// const wantPage = url.searchParams.get('page') === 'true';
|
||||||
|
// if (!wantPage) {
|
||||||
|
// const outboxUrl = makeUserUrl(this.webServer, user, '/ap/users/') + '/outbox';
|
||||||
|
// const body = JSON.stringify({
|
||||||
|
// '@context': ActivityStreamsContext,
|
||||||
|
// id: outboxUrl,
|
||||||
|
// type: 'OrderedCollection',
|
||||||
|
// first: `${outboxUrl}?page=true`,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const headers = {
|
||||||
|
// 'Content-Type': 'application/activity+json',
|
||||||
|
// 'Content-Length': body.length,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// resp.writeHead(200, headers);
|
||||||
|
// return resp.end(body);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Activity.fromOutboxEntries(user, this.webServer, (err, activity) => {
|
||||||
|
if (err) {
|
||||||
|
// :TODO: LOG ME
|
||||||
|
return this.webServer.internalServerError(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = JSON.stringify(activity);
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': ActivityJsonMime,
|
||||||
|
'Content-Length': body.length,
|
||||||
|
};
|
||||||
|
|
||||||
|
resp.writeHead(200, headers);
|
||||||
|
return resp.end(body);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_parseAndValidateSignature(req) {
|
||||||
|
let signature;
|
||||||
try {
|
try {
|
||||||
// :TODO: validate options passed to parseRequest()
|
// :TODO: validate options passed to parseRequest()
|
||||||
return httpSignature.parseRequest(req);
|
signature = httpSignature.parseRequest(req);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.log.warn(
|
this.log.warn(
|
||||||
{ error: e.message, url: req.url, method: req.method },
|
{ error: e.message, url: req.url, method: req.method },
|
||||||
'Failed to parse HTTP signature'
|
'Failed to parse HTTP signature'
|
||||||
);
|
);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// quick check up front
|
||||||
|
const keyId = signature.keyId;
|
||||||
|
if (!this._validateKeyId(keyId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
_validateKeyId(keyId) {
|
||||||
|
if (!keyId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only accept main-key currently
|
||||||
|
return keyId.endsWith('#main-key');
|
||||||
}
|
}
|
||||||
|
|
||||||
_inboxFollowRequestHandler(signature, activity, req, resp) {
|
_inboxFollowRequestHandler(signature, activity, req, resp) {
|
||||||
|
this.log.trace(
|
||||||
|
{ actor: activity.actor },
|
||||||
|
`Follow request from ${activity.actor}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// :TODO: trace
|
||||||
const accountName = accountFromSelfUrl(activity.object);
|
const accountName = accountFromSelfUrl(activity.object);
|
||||||
if (!accountName) {
|
if (!accountName) {
|
||||||
return this.webServer.badRequest(resp);
|
return this.webServer.badRequest(resp);
|
||||||
|
@ -266,15 +362,6 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_validateKeyId(keyId) {
|
|
||||||
if (!keyId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we only accept main-key currently
|
|
||||||
return keyId.endsWith('#main-key');
|
|
||||||
}
|
|
||||||
|
|
||||||
_authorizeInteractionHandler(req, resp) {
|
_authorizeInteractionHandler(req, resp) {
|
||||||
console.log(req);
|
console.log(req);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +381,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
const body = JSON.stringify(actor);
|
const body = JSON.stringify(actor);
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/activity+json',
|
'Content-Type': ActivityJsonMime,
|
||||||
'Content-Length': body.length,
|
'Content-Length': body.length,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue