Remove need for WebServer in a lot of areas, oputil ap condition functional
* Getting domain, URLs, etc. for local web server do not need a web server instance themselves * fix up oputil
This commit is contained in:
parent
e915527427
commit
fb02fc599a
|
@ -115,14 +115,14 @@ module.exports = class Actor extends ActivityPubObject {
|
|||
? user.getSanitizedName('real')
|
||||
: user.username,
|
||||
endpoints: {
|
||||
sharedInbox: Endpoints.sharedInbox(webServer),
|
||||
sharedInbox: Endpoints.sharedInbox(),
|
||||
},
|
||||
inbox: Endpoints.inbox(webServer, user),
|
||||
outbox: Endpoints.outbox(webServer, user),
|
||||
followers: Endpoints.followers(webServer, user),
|
||||
following: Endpoints.following(webServer, user),
|
||||
inbox: Endpoints.inbox(user),
|
||||
outbox: Endpoints.outbox(user),
|
||||
followers: Endpoints.followers(user),
|
||||
following: Endpoints.following(user),
|
||||
summary: user.getProperty(UserProps.AutoSignature) || '',
|
||||
url: Endpoints.profile(webServer, user),
|
||||
url: Endpoints.profile(user),
|
||||
manuallyApprovesFollowers: userSettings.manuallyApprovesFollowers,
|
||||
discoverable: userSettings.discoverable,
|
||||
// :TODO: we can start to define BBS related stuff with the community perhaps
|
||||
|
|
|
@ -84,7 +84,7 @@ module.exports = class Collection extends ActivityPubObject {
|
|||
}
|
||||
|
||||
static addFollower(owningUser, followingActor, webServer, ignoreDupes, cb) {
|
||||
const collectionId = Endpoints.followers(webServer, owningUser);
|
||||
const collectionId = Endpoints.followers(owningUser);
|
||||
return Collection.addToCollection(
|
||||
Collections.Followers,
|
||||
owningUser,
|
||||
|
@ -98,8 +98,7 @@ module.exports = class Collection extends ActivityPubObject {
|
|||
}
|
||||
|
||||
static addFollowRequest(owningUser, requestingActor, webServer, ignoreDupes, cb) {
|
||||
const collectionId =
|
||||
Endpoints.makeUserUrl(webServer, owningUser) + 'follow-requests';
|
||||
const collectionId = Endpoints.makeUserUrl(owningUser) + 'follow-requests';
|
||||
return Collection.addToCollection(
|
||||
Collections.FollowRequests,
|
||||
owningUser,
|
||||
|
@ -113,7 +112,7 @@ module.exports = class Collection extends ActivityPubObject {
|
|||
}
|
||||
|
||||
static addFollowing(owningUser, followingActor, webServer, ignoreDupes, cb) {
|
||||
const collectionId = Endpoints.following(webServer, owningUser);
|
||||
const collectionId = Endpoints.following(owningUser);
|
||||
return Collection.addToCollection(
|
||||
Collections.Following,
|
||||
owningUser,
|
||||
|
@ -127,7 +126,7 @@ module.exports = class Collection extends ActivityPubObject {
|
|||
}
|
||||
|
||||
static addOutboxItem(owningUser, outboxItem, isPrivate, webServer, ignoreDupes, cb) {
|
||||
const collectionId = Endpoints.outbox(webServer, owningUser);
|
||||
const collectionId = Endpoints.outbox(owningUser);
|
||||
return Collection.addToCollection(
|
||||
Collections.Outbox,
|
||||
owningUser,
|
||||
|
@ -141,7 +140,7 @@ module.exports = class Collection extends ActivityPubObject {
|
|||
}
|
||||
|
||||
static addInboxItem(inboxItem, owningUser, webServer, ignoreDupes, cb) {
|
||||
const collectionId = Endpoints.inbox(webServer, owningUser);
|
||||
const collectionId = Endpoints.inbox(owningUser);
|
||||
return Collection.addToCollection(
|
||||
Collections.Inbox,
|
||||
owningUser,
|
||||
|
@ -498,8 +497,7 @@ module.exports = class Collection extends ActivityPubObject {
|
|||
}
|
||||
|
||||
// e.g. http://somewhere.com/_enig/ap/users/NuSkooler/followers
|
||||
const collectionId =
|
||||
Endpoints.makeUserUrl(webServer, owningUser) + `/${collectionName}`;
|
||||
const collectionId = Endpoints.makeUserUrl(owningUser) + `/${collectionName}`;
|
||||
|
||||
if (!page) {
|
||||
return apDb.get(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const { WellKnownLocations } = require('../servers/content/web');
|
||||
const { buildUrl } = require('../web_util');
|
||||
|
||||
// deps
|
||||
const { v4: UUIDv4 } = require('uuid');
|
||||
|
@ -16,46 +17,42 @@ exports.objectId = objectId;
|
|||
|
||||
const ActivityPubUsersPrefix = '/ap/users/';
|
||||
|
||||
function makeUserUrl(webServer, user, relPrefix = ActivityPubUsersPrefix) {
|
||||
return webServer.buildUrl(
|
||||
WellKnownLocations.Internal + `${relPrefix}${user.username}`
|
||||
);
|
||||
function makeUserUrl(user, relPrefix = ActivityPubUsersPrefix) {
|
||||
return buildUrl(WellKnownLocations.Internal + `${relPrefix}${user.username}`);
|
||||
}
|
||||
|
||||
function inbox(webServer, user) {
|
||||
return makeUserUrl(webServer, user, ActivityPubUsersPrefix) + '/inbox';
|
||||
function inbox(user) {
|
||||
return makeUserUrl(user, ActivityPubUsersPrefix) + '/inbox';
|
||||
}
|
||||
|
||||
function outbox(webServer, user) {
|
||||
return makeUserUrl(webServer, user, ActivityPubUsersPrefix) + '/outbox';
|
||||
function outbox(user) {
|
||||
return makeUserUrl(user, ActivityPubUsersPrefix) + '/outbox';
|
||||
}
|
||||
|
||||
function followers(webServer, user) {
|
||||
return makeUserUrl(webServer, user, ActivityPubUsersPrefix) + '/followers';
|
||||
function followers(user) {
|
||||
return makeUserUrl(user, ActivityPubUsersPrefix) + '/followers';
|
||||
}
|
||||
|
||||
function following(webServer, user) {
|
||||
return makeUserUrl(webServer, user, ActivityPubUsersPrefix) + '/following';
|
||||
function following(user) {
|
||||
return makeUserUrl(user, ActivityPubUsersPrefix) + '/following';
|
||||
}
|
||||
|
||||
function actorId(webServer, user) {
|
||||
return makeUserUrl(webServer, user, ActivityPubUsersPrefix);
|
||||
function actorId(user) {
|
||||
return makeUserUrl(user, ActivityPubUsersPrefix);
|
||||
}
|
||||
|
||||
function profile(webServer, user) {
|
||||
return webServer.buildUrl(WellKnownLocations.Internal + `/wf/@${user.username}`);
|
||||
function profile(user) {
|
||||
return buildUrl(WellKnownLocations.Internal + `/wf/@${user.username}`);
|
||||
}
|
||||
|
||||
function avatar(webServer, user, filename) {
|
||||
return makeUserUrl(webServer, user, '/users/') + `/avatar/${filename}`;
|
||||
function avatar(user, filename) {
|
||||
return makeUserUrl(user, '/users/') + `/avatar/${filename}`;
|
||||
}
|
||||
|
||||
function sharedInbox(webServer) {
|
||||
return webServer.buildUrl(WellKnownLocations.Internal + '/ap/shared-inbox');
|
||||
function sharedInbox() {
|
||||
return buildUrl(WellKnownLocations.Internal + '/ap/shared-inbox');
|
||||
}
|
||||
|
||||
function objectId(webServer, objectType) {
|
||||
return webServer.buildUrl(
|
||||
WellKnownLocations.Internal + `/ap/${UUIDv4()}/${objectType}`
|
||||
);
|
||||
function objectId(objectType) {
|
||||
return buildUrl(WellKnownLocations.Internal + `/ap/${UUIDv4()}/${objectType}`);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ module.exports = class ActivityPubObject {
|
|||
}
|
||||
|
||||
static makeObjectId(webServer, objectType) {
|
||||
return Endpoints.objectId(webServer, objectType);
|
||||
return Endpoints.objectId(objectType);
|
||||
}
|
||||
|
||||
sendTo(inboxEndpoint, fromUser, webServer, cb) {
|
||||
|
@ -103,7 +103,7 @@ module.exports = class ActivityPubObject {
|
|||
},
|
||||
sign: {
|
||||
key: privateKey,
|
||||
keyId: Endpoints.actorId(webServer, fromUser) + '#main-key',
|
||||
keyId: Endpoints.actorId(fromUser) + '#main-key',
|
||||
authorizationHeaderName: 'Signature',
|
||||
headers: HttpSignatureSignHeaders,
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@ const { stripAnsiControlCodes } = require('../string_util');
|
|||
const { WellKnownRecipientFields } = require('./const');
|
||||
const Log = require('../logger').log;
|
||||
const { getWebDomain } = require('../web_util');
|
||||
const Endpoints = require('./endpoint');
|
||||
|
||||
// deps
|
||||
const _ = require('lodash');
|
||||
|
@ -30,6 +31,7 @@ exports.userNameFromSubject = userNameFromSubject;
|
|||
exports.userNameToSubject = userNameToSubject;
|
||||
exports.extractMessageMetadata = extractMessageMetadata;
|
||||
exports.recipientIdsFromObject = recipientIdsFromObject;
|
||||
exports.prepareLocalUserAsActor = prepareLocalUserAsActor;
|
||||
|
||||
// :TODO: more info in default
|
||||
// this profile template is the *default* for both WebFinger
|
||||
|
@ -262,3 +264,43 @@ function recipientIdsFromObject(obj) {
|
|||
|
||||
return Array.from(new Set(ids));
|
||||
}
|
||||
|
||||
function prepareLocalUserAsActor(user, options = { force: false }, cb) {
|
||||
const hasProps =
|
||||
user.getProperty(UserProps.ActivityPubActorId) &&
|
||||
user.getProperty(UserProps.PrivateActivityPubSigningKey) &&
|
||||
user.getProperty(UserProps.PublicActivityPubSigningKey);
|
||||
|
||||
if (hasProps && !options.force) {
|
||||
return cb(null);
|
||||
}
|
||||
|
||||
const actorId = Endpoints.actorId(user);
|
||||
user.setProperty(UserProps.ActivityPubActorId, actorId);
|
||||
|
||||
user.updateActivityPubKeyPairProperties(err => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
user.generateNewRandomAvatar((err, outPath) => {
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// :TODO: fetch over +op default overrides here, e.g. 'enabled'
|
||||
const apSettings = ActivityPubSettings.fromUser(user);
|
||||
|
||||
const filename = paths.basename(outPath);
|
||||
const avatarUrl = Endpoints.avatar(user, filename);
|
||||
|
||||
apSettings.image = avatarUrl;
|
||||
apSettings.icon = avatarUrl;
|
||||
|
||||
user.setProperty(UserProps.AvatarImageUrl, avatarUrl);
|
||||
user.setProperty(UserProps.ActivityPubSettings, JSON.stringify(apSettings));
|
||||
|
||||
return cb(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ const webServerPackageName = require('./servers/content/web.js').moduleInfo.pack
|
|||
const Events = require('./events.js');
|
||||
const UserProps = require('./user_property.js');
|
||||
const SysProps = require('./system_menu_method.js');
|
||||
const { buildUrl } = require('./web_util');
|
||||
|
||||
// deps
|
||||
const hashids = require('hashids/cjs');
|
||||
|
@ -202,11 +203,11 @@ class FileAreaWebAccess {
|
|||
buildSingleFileTempDownloadLink(client, fileEntry, hashId) {
|
||||
hashId = hashId || this.getSingleFileHashId(client, fileEntry);
|
||||
|
||||
return this.webServer.instance.buildUrl(`${Config().fileBase.web.path}${hashId}`);
|
||||
return buildUrl(`${Config().fileBase.web.path}${hashId}`);
|
||||
}
|
||||
|
||||
buildBatchArchiveTempDownloadLink(client, hashId) {
|
||||
return this.webServer.instance.buildUrl(`${Config().fileBase.web.path}${hashId}`);
|
||||
return buildUrl(`${Config().fileBase.web.path}${hashId}`);
|
||||
}
|
||||
|
||||
getExistingTempDownloadServeItem(client, fileEntry, cb) {
|
||||
|
|
|
@ -5,7 +5,6 @@ const {
|
|||
initConfigAndDatabases,
|
||||
} = require('./oputil_common');
|
||||
const getHelpFor = require('./oputil_help.js').getHelpFor;
|
||||
const UserProps = require('../user_property');
|
||||
const { Errors } = require('../enig_error');
|
||||
|
||||
// deps
|
||||
|
@ -48,24 +47,30 @@ function applyAction(username, actionFunc, cb) {
|
|||
});
|
||||
}
|
||||
|
||||
function conditionSingleUser(User, username, userId, settings, cb) {
|
||||
const { userNameToSubject } = require('../activitypub/util');
|
||||
const subject = userNameToSubject(username);
|
||||
function conditionSingleUser(user, cb) {
|
||||
const { userNameToSubject, prepareLocalUserAsActor } = require('../activitypub/util');
|
||||
|
||||
const subject = userNameToSubject(user.username);
|
||||
if (!subject) {
|
||||
return cb(Errors.General(`Failed to get subject for ${username}`));
|
||||
return cb(Errors.General(`Failed to get subject for ${user.username}`));
|
||||
}
|
||||
|
||||
console.info(`Conditioning ${username} (${userId}) -> ${subject}...`);
|
||||
|
||||
User.persistPropertyByUserId(userId, UserProps.ActivityPubSettings, settings, err => {
|
||||
console.info(`Conditioning ${user.username} (${user.userId}) -> ${subject}...`);
|
||||
prepareLocalUserAsActor(user, { force: argv.force }, err => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
user.persistProperties(user.properties, err => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function actionConditionAllUsers(_, cb) {
|
||||
const User = require('../../core/user.js');
|
||||
const ActivityPubSettings = require('../activitypub/settings');
|
||||
const defaultSettings = JSON.stringify(new ActivityPubSettings());
|
||||
|
||||
User.getUserList({}, (err, userList) => {
|
||||
if (err) {
|
||||
|
@ -75,13 +80,12 @@ function actionConditionAllUsers(_, cb) {
|
|||
async.each(
|
||||
userList,
|
||||
(entry, next) => {
|
||||
conditionSingleUser(
|
||||
User,
|
||||
entry.userName,
|
||||
entry.userId,
|
||||
defaultSettings,
|
||||
next
|
||||
);
|
||||
User.getUser(entry.userId, (err, user) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
return conditionSingleUser(user, next);
|
||||
});
|
||||
},
|
||||
err => {
|
||||
return cb(err);
|
||||
|
@ -90,13 +94,6 @@ function actionConditionAllUsers(_, cb) {
|
|||
});
|
||||
}
|
||||
|
||||
function actionConditionUser(user, cb) {
|
||||
const User = require('../../core/user.js');
|
||||
const ActivityPubSettings = require('../activitypub/settings');
|
||||
const defaultSettings = JSON.stringify(new ActivityPubSettings());
|
||||
return conditionSingleUser(User, user.username, user.userId, defaultSettings, cb);
|
||||
}
|
||||
|
||||
function validateActivityPub() {
|
||||
//
|
||||
// Web Server, and ActivityPub both must be enabled
|
||||
|
@ -116,7 +113,7 @@ function validateActivityPub() {
|
|||
function conditionUser(action, username) {
|
||||
return applyAction(
|
||||
username,
|
||||
'*' === username ? actionConditionAllUsers : actionConditionUser,
|
||||
'*' === username ? actionConditionAllUsers : conditionSingleUser,
|
||||
err => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
|
|
|
@ -10,6 +10,7 @@ const async = require('async');
|
|||
const inq = require('inquirer');
|
||||
const fs = require('fs');
|
||||
const hjson = require('hjson');
|
||||
const log = require('../../core/logger');
|
||||
|
||||
const packageJson = require('../../package.json');
|
||||
|
||||
|
@ -81,6 +82,7 @@ function initConfigAndDatabases(cb) {
|
|||
initConfig(callback);
|
||||
},
|
||||
function initDb(callback) {
|
||||
log.init();
|
||||
db.initializeDatabases(callback);
|
||||
},
|
||||
function initArchiveUtil(callback) {
|
||||
|
|
|
@ -215,6 +215,9 @@ Actions:
|
|||
condition USERNAME Condition user with system ActivityPub defaults
|
||||
|
||||
Instead of an actual USERNAME, the '*' character may be substituted.
|
||||
|
||||
condition arguments:
|
||||
--force Force condition; overrides any existing settings
|
||||
`,
|
||||
});
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ exports.getModule = class ActivityPubScannerTosser extends MessageScanTossModule
|
|||
}
|
||||
|
||||
_collectFollowersSharedInboxEndpoints(localUser, cb) {
|
||||
const localFollowersEndpoint = Endpoints.followers(this._webServer(), localUser);
|
||||
const localFollowersEndpoint = Endpoints.followers(localUser);
|
||||
|
||||
Collection.followers(localFollowersEndpoint, 'all', (err, collection) => {
|
||||
if (err) {
|
||||
|
|
|
@ -5,7 +5,6 @@ const Config = require('../../config.js').get;
|
|||
const { Errors } = require('../../enig_error.js');
|
||||
const { loadModulesForCategory, moduleCategories } = require('../../module_util');
|
||||
const WebHandlerModule = require('../../web_handler_module');
|
||||
const { getWebDomain } = require('../../web_util');
|
||||
|
||||
// deps
|
||||
const http = require('http');
|
||||
|
@ -90,53 +89,6 @@ exports.getModule = class WebServerModule extends ServerModule {
|
|||
return this.log;
|
||||
}
|
||||
|
||||
getDomain() {
|
||||
return getWebDomain();
|
||||
}
|
||||
|
||||
baseUrl() {
|
||||
const config = Config();
|
||||
const overridePrefix = _.get(config, 'contentServers.web.overrideUrlPrefix');
|
||||
if (overridePrefix) {
|
||||
return overridePrefix;
|
||||
}
|
||||
|
||||
let schema;
|
||||
let port;
|
||||
if (config.contentServers.web.https.enabled) {
|
||||
schema = 'https://';
|
||||
port =
|
||||
443 === config.contentServers.web.https.port
|
||||
? ''
|
||||
: `:${config.contentServers.web.https.port}`;
|
||||
} else {
|
||||
schema = 'http://';
|
||||
port =
|
||||
80 === config.contentServers.web.http.port
|
||||
? ''
|
||||
: `:${config.contentServers.web.http.port}`;
|
||||
}
|
||||
|
||||
return `${schema}${config.contentServers.web.domain}${port}`;
|
||||
}
|
||||
|
||||
fullUrl(req) {
|
||||
const base = this.baseUrl();
|
||||
return new URL(`${base}${req.url}`);
|
||||
}
|
||||
|
||||
buildUrl(pathAndQuery) {
|
||||
//
|
||||
// Create a URL such as
|
||||
// https://l33t.codes:44512/ + |pathAndQuery|
|
||||
//
|
||||
// Prefer HTTPS over HTTP. Be explicit about the port
|
||||
// only if non-standard. Allow users to override full prefix in config.
|
||||
//
|
||||
const base = this.baseUrl();
|
||||
return `${base}${pathAndQuery}`;
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.enableHttp || this.enableHttps;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ const {
|
|||
getUserProfileTemplatedBody,
|
||||
DefaultProfileTemplate,
|
||||
getActorId,
|
||||
prepareLocalUserAsActor,
|
||||
} = require('../../../activitypub/util');
|
||||
const Endpoints = require('../../../activitypub/endpoint');
|
||||
const {
|
||||
ActivityStreamMediaType,
|
||||
WellKnownActivity,
|
||||
|
@ -21,15 +21,14 @@ const Note = require('../../../activitypub/note');
|
|||
const EnigAssert = require('../../../enigma_assert');
|
||||
const Message = require('../../../message');
|
||||
const Events = require('../../../events');
|
||||
const UserProps = require('../../../user_property');
|
||||
const { Errors } = require('../../../enig_error');
|
||||
const { getFullUrl } = require('../../../web_util');
|
||||
|
||||
// deps
|
||||
const _ = require('lodash');
|
||||
const enigma_assert = require('../../../enigma_assert');
|
||||
const httpSignature = require('http-signature');
|
||||
const async = require('async');
|
||||
const paths = require('path');
|
||||
|
||||
exports.moduleInfo = {
|
||||
name: 'ActivityPub',
|
||||
|
@ -175,7 +174,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
_selfUrlRequestHandler(req, resp) {
|
||||
this.log.trace({ url: req.url }, 'Request for "self"');
|
||||
|
||||
let actorId = this.webServer.fullUrl(req).toString();
|
||||
let actorId = getFullUrl(req).toString();
|
||||
let sendActor = false;
|
||||
if (actorId.endsWith('.json')) {
|
||||
sendActor = true;
|
||||
|
@ -783,7 +782,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
|
||||
_localUserFromCollectionEndpoint(req, collectionName, cb) {
|
||||
// turn a collection URL to a Actor ID
|
||||
let actorId = this.webServer.fullUrl(req).toString();
|
||||
let actorId = getFullUrl(req).toString();
|
||||
const suffix = `/${collectionName}`;
|
||||
if (actorId.endsWith(suffix)) {
|
||||
actorId = actorId.slice(0, -suffix.length);
|
||||
|
@ -986,7 +985,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
return this.webServer.resourceNotFound(resp);
|
||||
}
|
||||
|
||||
const url = this.webServer.fullUrl(req);
|
||||
const url = getFullUrl(req);
|
||||
const page = url.searchParams.get('page');
|
||||
const collectionId = url.toString();
|
||||
|
||||
|
@ -1037,7 +1036,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
_singlePublicNoteGetHandler(req, resp) {
|
||||
this.log.debug({ url: req.url }, 'Request for "Note"');
|
||||
|
||||
const noteId = this.webServer.fullUrl(req).toString();
|
||||
const noteId = getFullUrl(req).toString();
|
||||
Note.fromPublicNoteId(noteId, (err, note) => {
|
||||
if (err) {
|
||||
return this.webServer.internalServerError(resp, err);
|
||||
|
@ -1180,42 +1179,6 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
`Preparing ActivityPub settings for "${user.username}"`
|
||||
);
|
||||
|
||||
const actorId = Endpoints.actorId(this.webServer, user);
|
||||
user.setProperty(UserProps.ActivityPubActorId, actorId);
|
||||
|
||||
user.updateActivityPubKeyPairProperties(err => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
user.generateNewRandomAvatar((err, outPath) => {
|
||||
if (err) {
|
||||
this.log.warn(
|
||||
{
|
||||
username: user.username,
|
||||
userId: user.userId,
|
||||
error: err.message,
|
||||
},
|
||||
`Failed to generate random avatar for "${user.username}"`
|
||||
);
|
||||
}
|
||||
|
||||
// :TODO: fetch over +op default overrides here, e.g. 'enabled'
|
||||
const apSettings = ActivityPubSettings.fromUser(user);
|
||||
|
||||
const filename = paths.basename(outPath);
|
||||
const avatarUrl = Endpoints.avatar(this.webServer, user, filename);
|
||||
|
||||
apSettings.image = avatarUrl;
|
||||
apSettings.icon = avatarUrl;
|
||||
|
||||
user.setProperty(
|
||||
UserProps.ActivityPubSettings,
|
||||
JSON.stringify(apSettings)
|
||||
);
|
||||
|
||||
return cb(null);
|
||||
});
|
||||
});
|
||||
return prepareLocalUserAsActor(user, cb);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@ const packageJson = require('../../../../package.json');
|
|||
const StatLog = require('../../../stat_log');
|
||||
const SysProps = require('../../../system_property');
|
||||
const SysLogKeys = require('../../../system_log');
|
||||
const { getBaseUrl, getWebDomain } = require('../../../web_util');
|
||||
|
||||
// deps
|
||||
const moment = require('moment');
|
||||
|
@ -30,7 +31,7 @@ exports.getModule = class NodeInfo2WebHandler extends WebHandlerModule {
|
|||
|
||||
this.log = webServer.logger().child({ webHandler: 'NodeInfo2' });
|
||||
|
||||
const domain = this.webServer.getDomain();
|
||||
const domain = getWebDomain();
|
||||
if (!domain) {
|
||||
return cb(Errors.UnexpectedState('Web server does not have "domain" set'));
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ exports.getModule = class NodeInfo2WebHandler extends WebHandlerModule {
|
|||
const nodeInfo = {
|
||||
version: '1.0',
|
||||
server: {
|
||||
baseUrl: this.webServer.baseUrl(),
|
||||
baseUrl: getBaseUrl(),
|
||||
name: config.general.boardName,
|
||||
software: 'ENiGMA½ Bulletin Board Software',
|
||||
version: packageJson.version,
|
||||
|
|
|
@ -2,6 +2,7 @@ const WebHandlerModule = require('../../../web_handler_module');
|
|||
const { Errors } = require('../../../enig_error');
|
||||
const EngiAssert = require('../../../enigma_assert');
|
||||
const Config = require('../../../config').get;
|
||||
const { getFullUrl, getWebDomain } = require('../../../web_util');
|
||||
|
||||
// deps
|
||||
const paths = require('path');
|
||||
|
@ -28,7 +29,7 @@ exports.getModule = class SystemGeneralWebHandler extends WebHandlerModule {
|
|||
|
||||
this.log = webServer.logger().child({ webHandler: 'SysGeneral' });
|
||||
|
||||
const domain = this.webServer.getDomain();
|
||||
const domain = getWebDomain();
|
||||
if (!domain) {
|
||||
return cb(Errors.UnexpectedState('Web server does not have "domain" set'));
|
||||
}
|
||||
|
@ -44,7 +45,7 @@ exports.getModule = class SystemGeneralWebHandler extends WebHandlerModule {
|
|||
}
|
||||
|
||||
_avatarGetHandler(req, resp) {
|
||||
const url = this.webServer.fullUrl(req);
|
||||
const url = getFullUrl(req);
|
||||
const filename = paths.basename(url.pathname);
|
||||
if (!filename) {
|
||||
return this.webServer.fileNotFound(resp);
|
||||
|
|
|
@ -11,6 +11,7 @@ const EngiAssert = require('../../../enigma_assert');
|
|||
const User = require('../../../user');
|
||||
const UserProps = require('../../../user_property');
|
||||
const ActivityPubSettings = require('../../../activitypub/settings');
|
||||
const { getFullUrl, buildUrl, getWebDomain } = require('../../../web_util');
|
||||
|
||||
// deps
|
||||
const _ = require('lodash');
|
||||
|
@ -38,7 +39,7 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
|
||||
this.log = webServer.logger().child({ webHandler: 'WebFinger' });
|
||||
|
||||
const domain = this.webServer.getDomain();
|
||||
const domain = getWebDomain();
|
||||
if (!domain) {
|
||||
return cb(Errors.UnexpectedState('Web server does not have "domain" set'));
|
||||
}
|
||||
|
@ -49,15 +50,9 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
new RegExp(`^acct:(.+)@${domain}$`),
|
||||
// profile page
|
||||
// https://webfinger.net/rel/profile-page/
|
||||
new RegExp(
|
||||
`^${this.webServer.buildUrl(WellKnownLocations.Internal + '/wf/@')}(.+)$`
|
||||
),
|
||||
new RegExp(`^${buildUrl(WellKnownLocations.Internal + '/wf/@')}(.+)$`),
|
||||
// self URL
|
||||
new RegExp(
|
||||
`^${this.webServer.buildUrl(
|
||||
WellKnownLocations.Internal + '/ap/users/'
|
||||
)}(.+)$`
|
||||
),
|
||||
new RegExp(`^${buildUrl(WellKnownLocations.Internal + '/ap/users/')}(.+)$`),
|
||||
];
|
||||
|
||||
this.webServer.addRoute({
|
||||
|
@ -78,7 +73,7 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
|
||||
_profileRequestHandler(req, resp) {
|
||||
// Profile requests do not have an Actor ID available
|
||||
const profileQuery = this.webServer.fullUrl(req).toString();
|
||||
const profileQuery = getFullUrl(req).toString();
|
||||
const accountName = this._getAccountName(profileQuery);
|
||||
if (!accountName) {
|
||||
this.log.warn(
|
||||
|
@ -135,7 +130,7 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
}
|
||||
|
||||
_webFingerRequestHandler(req, resp) {
|
||||
const url = this.webServer.fullUrl(req);
|
||||
const url = getFullUrl(req);
|
||||
const resource = url.searchParams.get('resource');
|
||||
if (!resource) {
|
||||
return this.webServer.respondWithError(
|
||||
|
@ -161,11 +156,10 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
return this.webServer.resourceNotFound(resp);
|
||||
}
|
||||
|
||||
const domain = this.webServer.getDomain();
|
||||
|
||||
const domain = getWebDomain();
|
||||
const body = JSON.stringify({
|
||||
subject: `acct:${localUser.username}@${domain}`,
|
||||
aliases: [this._profileUrl(localUser), this._userActorId(localUser)],
|
||||
aliases: [Endpoints.profile(localUser), Endpoints.actorId(localUser)],
|
||||
links: [
|
||||
this._profilePageLink(localUser),
|
||||
this._selfLink(localUser),
|
||||
|
@ -218,12 +212,8 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
});
|
||||
}
|
||||
|
||||
_profileUrl(user) {
|
||||
return Endpoints.profile(this.webServer, user);
|
||||
}
|
||||
|
||||
_profilePageLink(user) {
|
||||
const href = this._profileUrl(user);
|
||||
const href = Endpoints.profile(user);
|
||||
return {
|
||||
rel: 'http://webfinger.net/rel/profile-page',
|
||||
type: 'text/plain',
|
||||
|
@ -232,12 +222,12 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
}
|
||||
|
||||
_userActorId(user) {
|
||||
return Endpoints.actorId(this.webServer, user);
|
||||
return Endpoints.actorId(user);
|
||||
}
|
||||
|
||||
// :TODO: only if ActivityPub is enabled
|
||||
_selfLink(user) {
|
||||
const href = this._userActorId(user);
|
||||
const href = Endpoints.actorId(user);
|
||||
return {
|
||||
rel: 'self',
|
||||
type: 'application/activity+json',
|
||||
|
@ -249,7 +239,7 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
|
|||
_subscribeLink() {
|
||||
return {
|
||||
rel: 'http://ostatus.org/schema/1.0/subscribe',
|
||||
template: this.webServer.buildUrl(
|
||||
template: buildUrl(
|
||||
WellKnownLocations.Internal + '/ap/authorize_interaction?uri={uri}'
|
||||
),
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ const { sendMail } = require('./email.js');
|
|||
const UserProps = require('./user_property.js');
|
||||
const Log = require('./logger.js').log;
|
||||
const { getConnectionByUserId } = require('./client_connections.js');
|
||||
const { buildUrl } = require('./web_util');
|
||||
|
||||
// deps
|
||||
const async = require('async');
|
||||
|
@ -75,8 +76,7 @@ module.exports = class User2FA_OTPWebRegister {
|
|||
});
|
||||
},
|
||||
(token, textTemplate, htmlTemplate, callback) => {
|
||||
const webServer = getWebServer();
|
||||
const registerUrl = webServer.instance.buildUrl(
|
||||
const registerUrl = buildUrl(
|
||||
WellKnownLocations.Internal +
|
||||
`/2fa/enable_2fa_otp?token=${token}&otpType=${otpType}`
|
||||
);
|
||||
|
@ -172,7 +172,7 @@ module.exports = class User2FA_OTPWebRegister {
|
|||
return User2FA_OTPWebRegister.accessDenied(webServer, resp);
|
||||
}
|
||||
|
||||
const postUrl = webServer.instance.buildUrl(
|
||||
const postUrl = buildUrl(
|
||||
WellKnownLocations.Internal + '/2fa/enable_2fa_otp'
|
||||
);
|
||||
const config = Config();
|
||||
|
|
|
@ -70,6 +70,8 @@ module.exports = {
|
|||
PublicActivityPubSigningKey: 'public_key_activitypub_sign_rsa_pem', // RSA public key for ActivityPub signing
|
||||
PrivateActivityPubSigningKey: 'private_key_activitypub_sign_rsa_pem', // RSA private key (corresponding to PublicActivityPubSigningKey)
|
||||
|
||||
AvatarImageUrl: 'user_avatar_image',
|
||||
|
||||
ActivityPubSettings: 'activitypub_settings', // JSON object (above); see ActivityPubSettings in activitypub/settings.js
|
||||
ActivityPubActorId: 'activitypub_actor_id', // Actor ID representing this users
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ const userDb = require('./database.js').dbs.user;
|
|||
const getISOTimestampString = require('./database.js').getISOTimestampString;
|
||||
const Log = require('./logger.js').log;
|
||||
const UserProps = require('./user_property.js');
|
||||
const { buildUrl } = require('./web_util');
|
||||
|
||||
// deps
|
||||
const async = require('async');
|
||||
|
@ -121,7 +122,7 @@ class WebPasswordReset {
|
|||
function buildAndSendEmail(user, textTemplate, htmlTemplate, callback) {
|
||||
const sendMail = require('./email.js').sendMail;
|
||||
|
||||
const resetUrl = webServer.instance.buildUrl(
|
||||
const resetUrl = buildUrl(
|
||||
WellKnownLocations.Internal +
|
||||
`/sec/reset_password?token=${
|
||||
user.properties[UserProps.EmailPwResetToken]
|
||||
|
@ -271,7 +272,7 @@ class WebPasswordReset {
|
|||
);
|
||||
}
|
||||
|
||||
const postResetUrl = webServer.instance.buildUrl(
|
||||
const postResetUrl = buildUrl(
|
||||
WellKnownLocations.Internal + '/sec/reset_password'
|
||||
);
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ const Config = require('./config').get;
|
|||
const { get, isString } = require('lodash');
|
||||
|
||||
exports.getWebDomain = getWebDomain;
|
||||
exports.getBaseUrl = getBaseUrl;
|
||||
exports.getFullUrl = getFullUrl;
|
||||
exports.buildUrl = buildUrl;
|
||||
|
||||
function getWebDomain() {
|
||||
const config = Config();
|
||||
|
@ -15,3 +18,46 @@ function getWebDomain() {
|
|||
|
||||
return config.contentServers.web.domain;
|
||||
}
|
||||
|
||||
function getBaseUrl() {
|
||||
const config = Config();
|
||||
const overridePrefix = get(config, 'contentServers.web.overrideUrlPrefix');
|
||||
if (overridePrefix) {
|
||||
return overridePrefix;
|
||||
}
|
||||
|
||||
let schema;
|
||||
let port;
|
||||
if (config.contentServers.web.https.enabled) {
|
||||
schema = 'https://';
|
||||
port =
|
||||
443 === config.contentServers.web.https.port
|
||||
? ''
|
||||
: `:${config.contentServers.web.https.port}`;
|
||||
} else {
|
||||
schema = 'http://';
|
||||
port =
|
||||
80 === config.contentServers.web.http.port
|
||||
? ''
|
||||
: `:${config.contentServers.web.http.port}`;
|
||||
}
|
||||
|
||||
return `${schema}${config.contentServers.web.domain}${port}`;
|
||||
}
|
||||
|
||||
function getFullUrl(req) {
|
||||
const base = getBaseUrl();
|
||||
return new URL(`${base}${req.url}`);
|
||||
}
|
||||
|
||||
function buildUrl(pathAndQuery) {
|
||||
//
|
||||
// Create a URL such as
|
||||
// https://l33t.codes:44512/ + |pathAndQuery|
|
||||
//
|
||||
// Prefer HTTPS over HTTP. Be explicit about the port
|
||||
// only if non-standard. Allow users to override full prefix in config.
|
||||
//
|
||||
const base = getBaseUrl();
|
||||
return `${base}${pathAndQuery}`;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue