メンテナ情報をDBに保存するように
This commit is contained in:
		
							parent
							
								
									2de48110bb
								
							
						
					
					
						commit
						06b66f0209
					
				
					 15 changed files with 77 additions and 33 deletions
				
			
		| 
						 | 
					@ -1,10 +1,3 @@
 | 
				
			||||||
maintainer:
 | 
					 | 
				
			||||||
  name: example-maitainer-name # Your name
 | 
					 | 
				
			||||||
  url: http://example.com/ # Your contact (http or mailto)
 | 
					 | 
				
			||||||
  repository_url: https://github.com/syuilo/misskey # Repository URL
 | 
					 | 
				
			||||||
  feedback_url: https://github.com/syuilo/misskey/issues # Feedback URL (e.g. github issue)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Final accessible URL seen by a user.
 | 
					# Final accessible URL seen by a user.
 | 
				
			||||||
url: https://example.tld/
 | 
					url: https://example.tld/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1079,6 +1079,9 @@ admin/views/instance.vue:
 | 
				
			||||||
  instance-name: "インスタンス名"
 | 
					  instance-name: "インスタンス名"
 | 
				
			||||||
  instance-description: "インスタンスの紹介"
 | 
					  instance-description: "インスタンスの紹介"
 | 
				
			||||||
  banner-url: "バナー画像URL"
 | 
					  banner-url: "バナー画像URL"
 | 
				
			||||||
 | 
					  maintainer-config: "管理者情報"
 | 
				
			||||||
 | 
					  maintainer-name: "管理者名"
 | 
				
			||||||
 | 
					  maintainer-email: "管理者の連絡先"
 | 
				
			||||||
  drive-config: "ドライブの設定"
 | 
					  drive-config: "ドライブの設定"
 | 
				
			||||||
  cache-remote-files: "リモートのファイルをキャッシュする"
 | 
					  cache-remote-files: "リモートのファイルをキャッシュする"
 | 
				
			||||||
  cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
 | 
					  cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,11 @@
 | 
				
			||||||
			<ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea>
 | 
								<ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea>
 | 
				
			||||||
			<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>%i18n:@banner-url%</ui-input>
 | 
								<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>%i18n:@banner-url%</ui-input>
 | 
				
			||||||
		</section>
 | 
							</section>
 | 
				
			||||||
 | 
							<section class="fit-bottom">
 | 
				
			||||||
 | 
								<header><fa icon="headset"/> %i18n:@maintainer-config%</header>
 | 
				
			||||||
 | 
								<ui-input v-model="maintainerName">%i18n:@maintainer-name%</ui-input>
 | 
				
			||||||
 | 
								<ui-input v-model="maintainerEmail">%i18n:@maintainer-email%</ui-input>
 | 
				
			||||||
 | 
							</section>
 | 
				
			||||||
		<section class="fit-top fit-bottom">
 | 
							<section class="fit-top fit-bottom">
 | 
				
			||||||
			<ui-input v-model="maxNoteTextLength">%i18n:@max-note-text-length%</ui-input>
 | 
								<ui-input v-model="maxNoteTextLength">%i18n:@max-note-text-length%</ui-input>
 | 
				
			||||||
		</section>
 | 
							</section>
 | 
				
			||||||
| 
						 | 
					@ -56,6 +61,8 @@ import Vue from "vue";
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
 | 
								maintainerName: null,
 | 
				
			||||||
 | 
								maintainerEmail: null,
 | 
				
			||||||
			disableRegistration: false,
 | 
								disableRegistration: false,
 | 
				
			||||||
			disableLocalTimeline: false,
 | 
								disableLocalTimeline: false,
 | 
				
			||||||
			bannerUrl: null,
 | 
								bannerUrl: null,
 | 
				
			||||||
| 
						 | 
					@ -75,6 +82,8 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	created() {
 | 
						created() {
 | 
				
			||||||
		(this as any).os.getMeta().then(meta => {
 | 
							(this as any).os.getMeta().then(meta => {
 | 
				
			||||||
 | 
								this.maintainerName = meta.maintainer.name;
 | 
				
			||||||
 | 
								this.maintainerEmail = meta.maintainer.email;
 | 
				
			||||||
			this.bannerUrl = meta.bannerUrl;
 | 
								this.bannerUrl = meta.bannerUrl;
 | 
				
			||||||
			this.name = meta.name;
 | 
								this.name = meta.name;
 | 
				
			||||||
			this.description = meta.description;
 | 
								this.description = meta.description;
 | 
				
			||||||
| 
						 | 
					@ -103,6 +112,8 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		updateMeta() {
 | 
							updateMeta() {
 | 
				
			||||||
			(this as any).api('admin/update-meta', {
 | 
								(this as any).api('admin/update-meta', {
 | 
				
			||||||
 | 
									maintainerName: this.maintainerName,
 | 
				
			||||||
 | 
									maintainerEmail: this.maintainerEmail,
 | 
				
			||||||
				disableRegistration: this.disableRegistration,
 | 
									disableRegistration: this.disableRegistration,
 | 
				
			||||||
				disableLocalTimeline: this.disableLocalTimeline,
 | 
									disableLocalTimeline: this.disableLocalTimeline,
 | 
				
			||||||
				bannerUrl: this.bannerUrl,
 | 
									bannerUrl: this.bannerUrl,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
		<ui-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required styl="fill">
 | 
							<ui-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required styl="fill">
 | 
				
			||||||
			<span>%i18n:@invitation-code%</span>
 | 
								<span>%i18n:@invitation-code%</span>
 | 
				
			||||||
			<span slot="prefix"><fa icon="id-card-alt"/></span>
 | 
								<span slot="prefix"><fa icon="id-card-alt"/></span>
 | 
				
			||||||
			<p slot="desc" v-html="'%i18n:@invitation-info%'.replace('{}', meta.maintainer.url)"></p>
 | 
								<p slot="desc" v-html="'%i18n:@invitation-info%'.replace('{}', 'mailto:' + meta.maintainer.email)"></p>
 | 
				
			||||||
		</ui-input>
 | 
							</ui-input>
 | 
				
			||||||
		<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername" styl="fill">
 | 
							<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername" styl="fill">
 | 
				
			||||||
			<span>%i18n:@username%</span>
 | 
								<span>%i18n:@username%</span>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
			<h1><fa icon="heart"/>%i18n:@title%</h1>
 | 
								<h1><fa icon="heart"/>%i18n:@title%</h1>
 | 
				
			||||||
			<p v-if="meta">
 | 
								<p v-if="meta">
 | 
				
			||||||
				{{ '%i18n:@text%'.substr(0, '%i18n:@text%'.indexOf('{')) }}
 | 
									{{ '%i18n:@text%'.substr(0, '%i18n:@text%'.indexOf('{')) }}
 | 
				
			||||||
				<a :href="meta.maintainer.url">{{ meta.maintainer.name }}</a>
 | 
									<a :href="'mailto:' + meta.maintainer.email">{{ meta.maintainer.name }}</a>
 | 
				
			||||||
				{{ '%i18n:@text%'.substr('%i18n:@text%'.indexOf('}') + 1) }}
 | 
									{{ '%i18n:@text%'.substr('%i18n:@text%'.indexOf('}') + 1) }}
 | 
				
			||||||
			</p>
 | 
								</p>
 | 
				
			||||||
		</article>
 | 
							</article>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div class="info">
 | 
					<div class="info">
 | 
				
			||||||
	<p>Maintainer: <b><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></b></p>
 | 
						<p>Maintainer: <b><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></b></p>
 | 
				
			||||||
	<p>Machine: {{ meta.machine }}</p>
 | 
						<p>Machine: {{ meta.machine }}</p>
 | 
				
			||||||
	<p>Node: {{ meta.node }}</p>
 | 
						<p>Node: {{ meta.node }}</p>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -247,7 +247,7 @@
 | 
				
			||||||
		<ui-card class="other" v-show="page == 'other'">
 | 
							<ui-card class="other" v-show="page == 'other'">
 | 
				
			||||||
			<div slot="title"><fa icon="info-circle"/> %i18n:@about%</div>
 | 
								<div slot="title"><fa icon="info-circle"/> %i18n:@about%</div>
 | 
				
			||||||
			<section>
 | 
								<section>
 | 
				
			||||||
				<p v-if="meta">%i18n:@operator%: <i><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></i></p>
 | 
									<p v-if="meta">%i18n:@operator%: <i><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></i></p>
 | 
				
			||||||
			</section>
 | 
								</section>
 | 
				
			||||||
		</ui-card>
 | 
							</ui-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@
 | 
				
			||||||
					<div>
 | 
										<div>
 | 
				
			||||||
						<div v-if="meta" class="body">
 | 
											<div v-if="meta" class="body">
 | 
				
			||||||
							<p>Version: <b>{{ meta.version }}</b></p>
 | 
												<p>Version: <b>{{ meta.version }}</b></p>
 | 
				
			||||||
							<p>Maintainer: <b><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></b></p>
 | 
												<p>Maintainer: <b><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></b></p>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@
 | 
				
			||||||
		</article>
 | 
							</article>
 | 
				
			||||||
		<div class="info" v-if="meta">
 | 
							<div class="info" v-if="meta">
 | 
				
			||||||
			<p>Version: <b>{{ meta.version }}</b></p>
 | 
								<p>Version: <b>{{ meta.version }}</b></p>
 | 
				
			||||||
			<p>Maintainer: <b><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></b></p>
 | 
								<p>Maintainer: <b><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></b></p>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<footer>
 | 
							<footer>
 | 
				
			||||||
			<small>{{ copyright }}</small>
 | 
								<small>{{ copyright }}</small>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,22 +2,8 @@
 | 
				
			||||||
 * ユーザーが設定する必要のある情報
 | 
					 * ユーザーが設定する必要のある情報
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export type Source = {
 | 
					export type Source = {
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * メンテナ情報
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	maintainer: {
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * メンテナの名前
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		name: string;
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * メンテナの連絡先(URLかmailto形式のURL)
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		url: string;
 | 
					 | 
				
			||||||
		email?: string;
 | 
					 | 
				
			||||||
	repository_url?: string;
 | 
						repository_url?: string;
 | 
				
			||||||
	feedback_url?: string;
 | 
						feedback_url?: string;
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	languages?: string[];
 | 
						languages?: string[];
 | 
				
			||||||
	url: string;
 | 
						url: string;
 | 
				
			||||||
	port: number;
 | 
						port: number;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,17 +88,46 @@ if ((config as any).ghost) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					if ((config as any).maintainer) {
 | 
				
			||||||
 | 
						Meta.findOne({}).then(m => {
 | 
				
			||||||
 | 
							if (m != null && m.maintainer == null) {
 | 
				
			||||||
 | 
								Meta.update({}, {
 | 
				
			||||||
 | 
									$set: {
 | 
				
			||||||
 | 
										maintainer: (config as any).maintainer
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IMeta = {
 | 
					export type IMeta = {
 | 
				
			||||||
	name?: string;
 | 
						name?: string;
 | 
				
			||||||
	description?: string;
 | 
						description?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * メンテナ情報
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						maintainer: {
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * メンテナの名前
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * メンテナの連絡先
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							email?: string;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	broadcasts?: any[];
 | 
						broadcasts?: any[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stats?: {
 | 
						stats?: {
 | 
				
			||||||
		notesCount: number;
 | 
							notesCount: number;
 | 
				
			||||||
		originalNotesCount: number;
 | 
							originalNotesCount: number;
 | 
				
			||||||
		usersCount: number;
 | 
							usersCount: number;
 | 
				
			||||||
		originalUsersCount: number;
 | 
							originalUsersCount: number;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	disableRegistration?: boolean;
 | 
						disableRegistration?: boolean;
 | 
				
			||||||
	disableLocalTimeline?: boolean;
 | 
						disableLocalTimeline?: boolean;
 | 
				
			||||||
	hidedTags?: string[];
 | 
						hidedTags?: string[];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ import config from './config';
 | 
				
			||||||
if (config.sw) {
 | 
					if (config.sw) {
 | 
				
			||||||
	// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
 | 
						// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
 | 
				
			||||||
	push.setVapidDetails(
 | 
						push.setVapidDetails(
 | 
				
			||||||
		config.maintainer.url,
 | 
							config.url,
 | 
				
			||||||
		config.sw.public_key,
 | 
							config.sw.public_key,
 | 
				
			||||||
		config.sw.private_key);
 | 
							config.sw.private_key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,21 @@ export const meta = {
 | 
				
			||||||
		proxyAccount: {
 | 
							proxyAccount: {
 | 
				
			||||||
			validator: $.str.optional.nullable,
 | 
								validator: $.str.optional.nullable,
 | 
				
			||||||
			desc: {
 | 
								desc: {
 | 
				
			||||||
				'ja-JP': 'Proxy account username'
 | 
									'ja-JP': 'プロキシアカウントのユーザー名'
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							maintainerName: {
 | 
				
			||||||
 | 
								validator: $.str.optional,
 | 
				
			||||||
 | 
								desc: {
 | 
				
			||||||
 | 
									'ja-JP': 'インスタンスの管理者名'
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							maintainerEmail: {
 | 
				
			||||||
 | 
								validator: $.str.optional.nullable,
 | 
				
			||||||
 | 
								desc: {
 | 
				
			||||||
 | 
									'ja-JP': 'インスタンス管理者の連絡先メールアドレス'
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -183,6 +197,14 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
 | 
				
			||||||
		set.proxyAccount = ps.proxyAccount;
 | 
							set.proxyAccount = ps.proxyAccount;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ps.maintainerName !== undefined) {
 | 
				
			||||||
 | 
							set['maintainer.name'] = ps.maintainerName;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ps.maintainerEmail !== undefined) {
 | 
				
			||||||
 | 
							set['maintainer.email'] = ps.maintainerEmail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	await Meta.update({}, {
 | 
						await Meta.update({}, {
 | 
				
			||||||
		$set: set
 | 
							$set: set
 | 
				
			||||||
	}, { upsert: true });
 | 
						}, { upsert: true });
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const response: any = {
 | 
						const response: any = {
 | 
				
			||||||
		maintainer: config.maintainer,
 | 
							maintainer: instance.maintainer,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		version: pkg.version,
 | 
							version: pkg.version,
 | 
				
			||||||
		clientVersion: client.version,
 | 
							clientVersion: client.version,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ router.get('/v1/instance', async ctx => { // TODO: This is a temporary implement
 | 
				
			||||||
		uri: config.hostname,
 | 
							uri: config.hostname,
 | 
				
			||||||
		title: meta.name || 'Misskey',
 | 
							title: meta.name || 'Misskey',
 | 
				
			||||||
		description: meta.description || '',
 | 
							description: meta.description || '',
 | 
				
			||||||
		email: config.maintainer.email || config.maintainer.url.startsWith('mailto:') ? config.maintainer.url.slice(7) : '',
 | 
							email: meta.maintainer.email,
 | 
				
			||||||
		version: `0.0.0:compatible:misskey:${pkg.version}`, // TODO: How to tell about that this is an api for compatibility?
 | 
							version: `0.0.0:compatible:misskey:${pkg.version}`, // TODO: How to tell about that this is an api for compatibility?
 | 
				
			||||||
		thumbnail: meta.bannerUrl,
 | 
							thumbnail: meta.bannerUrl,
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue