diff options
| -rw-r--r-- | .config/example.yml | 5 | ||||
| -rw-r--r-- | locales/ja-JP.yml | 5 | ||||
| -rw-r--r-- | src/client/app/admin/views/instance.vue | 15 | ||||
| -rw-r--r-- | src/config/types.ts | 5 | ||||
| -rw-r--r-- | src/models/meta.ts | 16 | ||||
| -rw-r--r-- | src/models/user.ts | 6 | ||||
| -rw-r--r-- | src/server/api/endpoints/admin/update-meta.ts | 15 | ||||
| -rw-r--r-- | src/server/api/endpoints/meta.ts | 1 | ||||
| -rw-r--r-- | src/server/api/endpoints/users/lists/push.ts | 8 |
9 files changed, 55 insertions, 21 deletions
diff --git a/.config/example.yml b/.config/example.yml index 7918d766ed..2fd57094b6 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -135,11 +135,6 @@ autoAdmin: true # client_id: example-github-client-id # client_secret: example-github-client-secret -# Ghost -# Ghost account is an account used for the purpose of delegating -# followers when putting users in the list. -#ghost: user-id-of-your-ghost-account - # Clustering #clusterLimit: 1 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 840dce5735..2d0cf60bc6 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1090,6 +1090,11 @@ admin/views/instance.vue: enable-recaptcha: "reCAPTCHAを有効にする" recaptcha-site-key: "reCAPTCHA site key" recaptcha-secret-key: "reCAPTCHA secret key" + proxy-account-config: "プロキシアカウントの設定" + proxy-account-info: "プロキシアカウントは、特定の条件下でユーザーのリモートフォローを代行するアカウントです。例えば、ユーザーがリモートユーザーをリストに入れたとき、リストに入れられたユーザーを誰もフォローしていないとアクティビティがサーバーに配達されないため、代わりにプロキシアカウントがフォローするようにします。" + proxy-account-username: "プロキシアカウントのユーザー名" + proxy-account-username-desc: "プロキシとして使用するアカウントのユーザー名を指定してください。" + proxy-account-warn: "アカウントは自動で作られないため、そのユーザー名のアカウントを予め作成しておく必要があります。" max-note-text-length: "投稿の最大文字数" disable-registration: "ユーザー登録の受付を停止する" disable-local-timeline: "ローカルタイムラインを無効にする" diff --git a/src/client/app/admin/views/instance.vue b/src/client/app/admin/views/instance.vue index 11f9d28fd2..5acb493332 100644 --- a/src/client/app/admin/views/instance.vue +++ b/src/client/app/admin/views/instance.vue @@ -13,8 +13,8 @@ <section class="fit-bottom"> <header><fa icon="cloud"/> %i18n:@drive-config%</header> <ui-switch v-model="cacheRemoteFiles">%i18n:@cache-remote-files%<span slot="desc">%i18n:@cache-remote-files-desc%</span></ui-switch> - <ui-input v-model="localDriveCapacityMb">%i18n:@local-drive-capacity-mb%<span slot="desc">%i18n:@mb%</span><span slot="suffix">MB</span></ui-input> - <ui-input v-model="remoteDriveCapacityMb" :disabled="!cacheRemoteFiles">%i18n:@remote-drive-capacity-mb%<span slot="desc">%i18n:@mb%</span><span slot="suffix">MB</span></ui-input> + <ui-input v-model="localDriveCapacityMb">%i18n:@local-drive-capacity-mb%<span slot="suffix">MB</span><span slot="desc">%i18n:@mb%</span></ui-input> + <ui-input v-model="remoteDriveCapacityMb" :disabled="!cacheRemoteFiles">%i18n:@remote-drive-capacity-mb%<span slot="suffix">MB</span><span slot="desc">%i18n:@mb%</span></ui-input> </section> <section class="fit-bottom"> <header><fa icon="shield-alt"/> %i18n:@recaptcha-config%</header> @@ -24,6 +24,12 @@ <ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>%i18n:@recaptcha-secret-key%</ui-input> </section> <section> + <header><fa icon="ghost"/> %i18n:@proxy-account-config%</header> + <ui-info>%i18n:@proxy-account-info%</ui-info> + <ui-input v-model="proxyAccount"><i slot="prefix">@</i>%i18n:@proxy-account-username%<span slot="desc">%i18n:@proxy-account-username-desc%</span></ui-input> + <ui-info warn>%i18n:@proxy-account-warn%</ui-info> + </section> + <section> <ui-switch v-model="disableRegistration">%i18n:@disable-registration%</ui-switch> </section> <section> @@ -62,6 +68,7 @@ export default Vue.extend({ enableRecaptcha: false, recaptchaSiteKey: null, recaptchaSecretKey: null, + proxyAccount: null, inviteCode: null, }; }, @@ -78,6 +85,7 @@ export default Vue.extend({ this.enableRecaptcha = meta.enableRecaptcha; this.recaptchaSiteKey = meta.recaptchaSiteKey; this.recaptchaSecretKey = meta.recaptchaSecretKey; + this.proxyAccount = meta.proxyAccount; }); }, @@ -106,7 +114,8 @@ export default Vue.extend({ maxNoteTextLength: parseInt(this.maxNoteTextLength, 10), enableRecaptcha: this.enableRecaptcha, recaptchaSiteKey: this.recaptchaSiteKey, - recaptchaSecretKey: this.recaptchaSecretKey + recaptchaSecretKey: this.recaptchaSecretKey, + proxyAccount: this.proxyAccount, }).then(() => { this.$swal({ type: 'success', diff --git a/src/config/types.ts b/src/config/types.ts index 07d2ec318f..1e44c4061e 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -50,11 +50,6 @@ export type Source = { autoAdmin?: boolean; - /** - * ゴーストアカウントのID - */ - ghost?: string; - proxy?: string; summalyProxy?: string; diff --git a/src/models/meta.ts b/src/models/meta.ts index 3eb73681ac..5d03d94181 100644 --- a/src/models/meta.ts +++ b/src/models/meta.ts @@ -1,5 +1,7 @@ import db from '../db/mongodb'; import config from '../config'; +import User from './user'; +import { transform } from '../misc/cafy-id'; const Meta = db.get<IMeta>('meta'); export default Meta; @@ -74,6 +76,18 @@ if ((config as any).recaptcha) { } }); } +if ((config as any).ghost) { + Meta.findOne({}).then(async m => { + if (m != null && m.proxyAccount == null) { + const account = await User.findOne({ _id: transform((config as any).ghost) }); + Meta.update({}, { + $set: { + proxyAccount: account.username + } + }); + } + }); +} export type IMeta = { name?: string; @@ -92,6 +106,8 @@ export type IMeta = { cacheRemoteFiles?: boolean; + proxyAccount?: string; + enableRecaptcha?: boolean; recaptchaSiteKey?: string; recaptchaSecretKey?: string; diff --git a/src/models/user.ts b/src/models/user.ts index 43ca612b51..2ca1917dc9 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -10,6 +10,7 @@ import Mute from './mute'; import { getFriendIds } from '../server/api/common/get-friends'; import config from '../config'; import FollowRequest from './follow-request'; +import fetchMeta from '../misc/fetch-meta'; const User = db.get<IUser>('users'); @@ -376,6 +377,7 @@ function img(url) { } */ -export function getGhost(): Promise<ILocalUser> { - return User.findOne({ _id: new mongo.ObjectId(config.ghost) }); +export async function fetchProxyAccount(): Promise<ILocalUser> { + const meta = await fetchMeta(); + return await User.findOne({ username: meta.proxyAccount, host: null }) as ILocalUser; } diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index 85266b47cf..f541409274 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -98,17 +98,24 @@ export const meta = { }, recaptchaSiteKey: { - validator: $.str.optional, + validator: $.str.optional.nullable, desc: { 'ja-JP': 'reCAPTCHA site key' } }, recaptchaSecretKey: { - validator: $.str.optional, + validator: $.str.optional.nullable, desc: { 'ja-JP': 'reCAPTCHA secret key' } + }, + + proxyAccount: { + validator: $.str.optional.nullable, + desc: { + 'ja-JP': 'Proxy account username' + } } } }; @@ -172,6 +179,10 @@ export default define(meta, (ps) => new Promise(async (res, rej) => { set.recaptchaSecretKey = ps.recaptchaSecretKey; } + if (ps.proxyAccount !== undefined) { + set.proxyAccount = ps.proxyAccount; + } + await Meta.update({}, { $set: set }, { upsert: true }); diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 3ed225cc5f..03d2d9c6eb 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -85,6 +85,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { if (me && me.isAdmin) { response.hidedTags = instance.hidedTags; response.recaptchaSecretKey = instance.recaptchaSecretKey; + response.proxyAccount = instance.proxyAccount; } res(response); diff --git a/src/server/api/endpoints/users/lists/push.ts b/src/server/api/endpoints/users/lists/push.ts index 396f9813a4..5612ff1665 100644 --- a/src/server/api/endpoints/users/lists/push.ts +++ b/src/server/api/endpoints/users/lists/push.ts @@ -1,6 +1,6 @@ import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id'; import UserList from '../../../../../models/user-list'; -import User, { pack as packUser, isRemoteUser, getGhost } from '../../../../../models/user'; +import User, { pack as packUser, isRemoteUser, fetchProxyAccount } from '../../../../../models/user'; import { publishUserListStream } from '../../../../../stream'; import ap from '../../../../../remote/activitypub/renderer'; import renderFollow from '../../../../../remote/activitypub/renderer/follow'; @@ -71,8 +71,8 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { // このインスタンス内にこのリモートユーザーをフォローしているユーザーがいなくても投稿を受け取るためにダミーのユーザーがフォローしたということにする if (isRemoteUser(user)) { - const ghost = await getGhost(); - const content = ap(renderFollow(ghost, user)); - deliver(ghost, content, user.inbox); + const proxy = await fetchProxyAccount(); + const content = ap(renderFollow(proxy, user)); + deliver(proxy, content, user.inbox); } })); |