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