Resolve #3687
This commit is contained in:
		
							parent
							
								
									710ba526fa
								
							
						
					
					
						commit
						454632d785
					
				
					 9 changed files with 91 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -1164,6 +1164,12 @@ admin/views/instance.vue:
 | 
			
		|||
  smtp-port: "SMTPポート"
 | 
			
		||||
  smtp-user: "SMTPユーザー"
 | 
			
		||||
  smtp-pass: "SMTPパスワード"
 | 
			
		||||
  serviceworker-config: "ServiceWorker"
 | 
			
		||||
  enable-serviceworker: "ServiceWorkerを有効にする"
 | 
			
		||||
  serviceworker-info: "プッシュ通知を行うには有効する必要があります。"
 | 
			
		||||
  vapid-publickey: "VAPID公開鍵"
 | 
			
		||||
  vapid-privatekey: "VAPID秘密鍵"
 | 
			
		||||
  vapid-info: "ServiceWorkerを有効にする場合、VAPIDキーペアを生成する必要があります。シェルで次のようにします:"
 | 
			
		||||
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,15 @@
 | 
			
		|||
			</ui-horizon-group>
 | 
			
		||||
			<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<span slot="desc">{{ $t('smtp-secure-info') }}</span></ui-switch>
 | 
			
		||||
		</section>
 | 
			
		||||
		<section>
 | 
			
		||||
			<header><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</header>
 | 
			
		||||
			<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<span slot="desc">{{ $t('serviceworker-info') }}</span></ui-switch>
 | 
			
		||||
			<ui-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></ui-info>
 | 
			
		||||
			<ui-horizon-group inputs class="fit-bottom">
 | 
			
		||||
				<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><i slot="icon"><fa icon="key"/></i>{{ $t('vapid-publickey') }}</ui-input>
 | 
			
		||||
				<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><i slot="icon"><fa icon="key"/></i>{{ $t('vapid-privatekey') }}</ui-input>
 | 
			
		||||
			</ui-horizon-group>
 | 
			
		||||
		</section>
 | 
			
		||||
		<section>
 | 
			
		||||
			<header>summaly Proxy</header>
 | 
			
		||||
			<ui-input v-model="summalyProxy">URL</ui-input>
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +135,7 @@ import Vue from 'vue';
 | 
			
		|||
import i18n from '../../i18n';
 | 
			
		||||
import { url, host } from '../../config';
 | 
			
		||||
import { toUnicode } from 'punycode';
 | 
			
		||||
import { faHeadset, faShieldAlt, faGhost, faUserPlus } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
import { faHeadset, faShieldAlt, faGhost, faUserPlus, faBolt } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
import { faEnvelope as farEnvelope } from '@fortawesome/free-regular-svg-icons';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
| 
						 | 
				
			
			@ -174,7 +183,10 @@ export default Vue.extend({
 | 
			
		|||
			smtpPort: null,
 | 
			
		||||
			smtpUser: null,
 | 
			
		||||
			smtpPass: null,
 | 
			
		||||
			faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope
 | 
			
		||||
			enableServiceWorker: false,
 | 
			
		||||
			swPublicKey: null,
 | 
			
		||||
			swPrivateKey: null,
 | 
			
		||||
			faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -217,6 +229,9 @@ export default Vue.extend({
 | 
			
		|||
			this.smtpPort = meta.smtpPort;
 | 
			
		||||
			this.smtpUser = meta.smtpUser;
 | 
			
		||||
			this.smtpPass = meta.smtpPass;
 | 
			
		||||
			this.enableServiceWorker = meta.enableServiceWorker;
 | 
			
		||||
			this.swPublicKey = meta.swPublickey;
 | 
			
		||||
			this.swPrivateKey = meta.swPrivateKey;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +285,10 @@ export default Vue.extend({
 | 
			
		|||
				smtpHost: this.smtpHost,
 | 
			
		||||
				smtpPort: parseInt(this.smtpPort, 10),
 | 
			
		||||
				smtpUser: this.smtpUser,
 | 
			
		||||
				smtpPass: this.smtpPass
 | 
			
		||||
				smtpPass: this.smtpPass,
 | 
			
		||||
				enableServiceWorker: this.enableServiceWorker,
 | 
			
		||||
				swPublicKey: this.swPublicKey,
 | 
			
		||||
				swPrivateKey: this.swPrivateKey
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.$root.dialog({
 | 
			
		||||
					type: 'success',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,14 +39,6 @@ export type Source = {
 | 
			
		|||
 | 
			
		||||
	accesslog?: string;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Service Worker
 | 
			
		||||
	 */
 | 
			
		||||
	sw?: {
 | 
			
		||||
		publicKey: string;
 | 
			
		||||
		privateKey: string;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	clusterLimit?: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,8 @@ const defaultMeta: any = {
 | 
			
		|||
	enableExternalUserRecommendation: false,
 | 
			
		||||
	externalUserRecommendationEngine: 'https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}',
 | 
			
		||||
	externalUserRecommendationTimeout: 300000,
 | 
			
		||||
	errorImageUrl: 'https://ai.misskey.xyz/aiart/yubitun.png'
 | 
			
		||||
	errorImageUrl: 'https://ai.misskey.xyz/aiart/yubitun.png',
 | 
			
		||||
	enableServiceWorker: false
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default async function(): Promise<IMeta> {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -223,4 +223,8 @@ export type IMeta = {
 | 
			
		|||
	smtpPort?: number;
 | 
			
		||||
	smtpUser?: string;
 | 
			
		||||
	smtpPass?: string;
 | 
			
		||||
 | 
			
		||||
	enableServiceWorker?: boolean;
 | 
			
		||||
	swPublicKey?: string;
 | 
			
		||||
	swPrivateKey?: string;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,17 +2,26 @@ const push = require('web-push');
 | 
			
		|||
import * as mongo from 'mongodb';
 | 
			
		||||
import Subscription from './models/sw-subscription';
 | 
			
		||||
import config from './config';
 | 
			
		||||
import fetchMeta from './misc/fetch-meta';
 | 
			
		||||
import { IMeta } from './models/meta';
 | 
			
		||||
 | 
			
		||||
if (config.sw) {
 | 
			
		||||
let meta: IMeta = null;
 | 
			
		||||
 | 
			
		||||
setInterval(() => {
 | 
			
		||||
	fetchMeta().then(m => {
 | 
			
		||||
		meta = m;
 | 
			
		||||
 | 
			
		||||
		if (meta.enableServiceWorker) {
 | 
			
		||||
			// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
 | 
			
		||||
	push.setVapidDetails(
 | 
			
		||||
		config.url,
 | 
			
		||||
		config.sw.publicKey,
 | 
			
		||||
		config.sw.privateKey);
 | 
			
		||||
			push.setVapidDetails(config.url,
 | 
			
		||||
				meta.swPublicKey,
 | 
			
		||||
				meta.swPrivateKey);
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
}, 3000);
 | 
			
		||||
 | 
			
		||||
export default async function(userId: mongo.ObjectID | string, type: string, body?: any) {
 | 
			
		||||
	if (!config.sw) return;
 | 
			
		||||
	if (!meta.enableServiceWorker) return;
 | 
			
		||||
 | 
			
		||||
	if (typeof userId === 'string') {
 | 
			
		||||
		userId = new mongo.ObjectID(userId);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -285,6 +285,27 @@ export const meta = {
 | 
			
		|||
				'ja-JP': 'SMTPサーバのパスワード'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		enableServiceWorker: {
 | 
			
		||||
			validator: $.bool.optional,
 | 
			
		||||
			desc: {
 | 
			
		||||
				'ja-JP': 'ServiceWorkerを有効にするか否か'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		swPublicKey: {
 | 
			
		||||
			validator: $.str.optional.nullable,
 | 
			
		||||
			desc: {
 | 
			
		||||
				'ja-JP': 'ServiceWorkerのVAPIDキーペアの公開鍵'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		swPrivateKey: {
 | 
			
		||||
			validator: $.str.optional.nullable,
 | 
			
		||||
			desc: {
 | 
			
		||||
				'ja-JP': 'ServiceWorkerのVAPIDキーペアの秘密鍵'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -447,6 +468,18 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
 | 
			
		|||
		set.errorImageUrl = ps.errorImageUrl;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ps.enableServiceWorker !== undefined) {
 | 
			
		||||
		set.enableServiceWorker = ps.enableServiceWorker;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ps.swPublicKey !== undefined) {
 | 
			
		||||
		set.swPublicKey = ps.swPublicKey;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ps.swPrivateKey !== undefined) {
 | 
			
		||||
		set.swPrivateKey = ps.swPrivateKey;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	await Meta.update({}, {
 | 
			
		||||
		$set: set
 | 
			
		||||
	}, { upsert: true });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 | 
			
		|||
		cacheRemoteFiles: instance.cacheRemoteFiles,
 | 
			
		||||
		enableRecaptcha: instance.enableRecaptcha,
 | 
			
		||||
		recaptchaSiteKey: instance.recaptchaSiteKey,
 | 
			
		||||
		swPublickey: null,
 | 
			
		||||
		swPublickey: instance.swPublicKey,
 | 
			
		||||
		bannerUrl: instance.bannerUrl,
 | 
			
		||||
		errorImageUrl: instance.errorImageUrl,
 | 
			
		||||
		maxNoteTextLength: instance.maxNoteTextLength,
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 | 
			
		|||
			twitter: instance.enableTwitterIntegration,
 | 
			
		||||
			github: instance.enableGithubIntegration,
 | 
			
		||||
			discord: instance.enableDiscordIntegration,
 | 
			
		||||
			serviceWorker: config.sw ? true : false,
 | 
			
		||||
			serviceWorker: instance.enableServiceWorker,
 | 
			
		||||
			userRecommendation: {
 | 
			
		||||
				external: instance.enableExternalUserRecommendation,
 | 
			
		||||
				engine: instance.externalUserRecommendationEngine,
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +114,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 | 
			
		|||
		response.smtpPort = instance.smtpPort;
 | 
			
		||||
		response.smtpUser = instance.smtpUser;
 | 
			
		||||
		response.smtpPass = instance.smtpPass;
 | 
			
		||||
		response.swPrivateKey = instance.swPrivateKey;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res(response);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import $ from 'cafy';
 | 
			
		||||
import Subscription from '../../../../models/sw-subscription';
 | 
			
		||||
import config from '../../../../config';
 | 
			
		||||
import define from '../../define';
 | 
			
		||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	requireCredential: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -31,10 +31,12 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 | 
			
		|||
		deletedAt: { $exists: false }
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const instance = await fetchMeta();
 | 
			
		||||
 | 
			
		||||
	if (exist != null) {
 | 
			
		||||
		return res({
 | 
			
		||||
			state: 'already-subscribed',
 | 
			
		||||
			key: config.sw.publicKey
 | 
			
		||||
			key: instance.swPublicKey
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +49,6 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 | 
			
		|||
 | 
			
		||||
	res({
 | 
			
		||||
		state: 'subscribed',
 | 
			
		||||
		key: config.sw.publicKey
 | 
			
		||||
		key: instance.swPublicKey
 | 
			
		||||
	});
 | 
			
		||||
}));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue