Resolve #3687
This commit is contained in:
parent
710ba526fa
commit
454632d785
|
@ -1164,6 +1164,12 @@ admin/views/instance.vue:
|
||||||
smtp-port: "SMTPポート"
|
smtp-port: "SMTPポート"
|
||||||
smtp-user: "SMTPユーザー"
|
smtp-user: "SMTPユーザー"
|
||||||
smtp-pass: "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:
|
admin/views/charts.vue:
|
||||||
title: "チャート"
|
title: "チャート"
|
||||||
|
|
|
@ -57,6 +57,15 @@
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<span slot="desc">{{ $t('smtp-secure-info') }}</span></ui-switch>
|
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<span slot="desc">{{ $t('smtp-secure-info') }}</span></ui-switch>
|
||||||
</section>
|
</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>
|
<section>
|
||||||
<header>summaly Proxy</header>
|
<header>summaly Proxy</header>
|
||||||
<ui-input v-model="summalyProxy">URL</ui-input>
|
<ui-input v-model="summalyProxy">URL</ui-input>
|
||||||
|
@ -126,7 +135,7 @@ import Vue from 'vue';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
import { url, host } from '../../config';
|
import { url, host } from '../../config';
|
||||||
import { toUnicode } from 'punycode';
|
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';
|
import { faEnvelope as farEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
@ -174,7 +183,10 @@ export default Vue.extend({
|
||||||
smtpPort: null,
|
smtpPort: null,
|
||||||
smtpUser: null,
|
smtpUser: null,
|
||||||
smtpPass: 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.smtpPort = meta.smtpPort;
|
||||||
this.smtpUser = meta.smtpUser;
|
this.smtpUser = meta.smtpUser;
|
||||||
this.smtpPass = meta.smtpPass;
|
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,
|
smtpHost: this.smtpHost,
|
||||||
smtpPort: parseInt(this.smtpPort, 10),
|
smtpPort: parseInt(this.smtpPort, 10),
|
||||||
smtpUser: this.smtpUser,
|
smtpUser: this.smtpUser,
|
||||||
smtpPass: this.smtpPass
|
smtpPass: this.smtpPass,
|
||||||
|
enableServiceWorker: this.enableServiceWorker,
|
||||||
|
swPublicKey: this.swPublicKey,
|
||||||
|
swPrivateKey: this.swPrivateKey
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$root.dialog({
|
this.$root.dialog({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
|
|
@ -39,14 +39,6 @@ export type Source = {
|
||||||
|
|
||||||
accesslog?: string;
|
accesslog?: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Service Worker
|
|
||||||
*/
|
|
||||||
sw?: {
|
|
||||||
publicKey: string;
|
|
||||||
privateKey: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
clusterLimit?: number;
|
clusterLimit?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ const defaultMeta: any = {
|
||||||
enableExternalUserRecommendation: false,
|
enableExternalUserRecommendation: false,
|
||||||
externalUserRecommendationEngine: 'https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}',
|
externalUserRecommendationEngine: 'https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}',
|
||||||
externalUserRecommendationTimeout: 300000,
|
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> {
|
export default async function(): Promise<IMeta> {
|
||||||
|
|
|
@ -223,4 +223,8 @@ export type IMeta = {
|
||||||
smtpPort?: number;
|
smtpPort?: number;
|
||||||
smtpUser?: string;
|
smtpUser?: string;
|
||||||
smtpPass?: string;
|
smtpPass?: string;
|
||||||
|
|
||||||
|
enableServiceWorker?: boolean;
|
||||||
|
swPublicKey?: string;
|
||||||
|
swPrivateKey?: string;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,17 +2,26 @@ const push = require('web-push');
|
||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
import Subscription from './models/sw-subscription';
|
import Subscription from './models/sw-subscription';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
|
import fetchMeta from './misc/fetch-meta';
|
||||||
|
import { IMeta } from './models/meta';
|
||||||
|
|
||||||
if (config.sw) {
|
let meta: IMeta = null;
|
||||||
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
|
|
||||||
push.setVapidDetails(
|
setInterval(() => {
|
||||||
config.url,
|
fetchMeta().then(m => {
|
||||||
config.sw.publicKey,
|
meta = m;
|
||||||
config.sw.privateKey);
|
|
||||||
}
|
if (meta.enableServiceWorker) {
|
||||||
|
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
|
||||||
|
push.setVapidDetails(config.url,
|
||||||
|
meta.swPublicKey,
|
||||||
|
meta.swPrivateKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
export default async function(userId: mongo.ObjectID | string, type: string, body?: any) {
|
export default async function(userId: mongo.ObjectID | string, type: string, body?: any) {
|
||||||
if (!config.sw) return;
|
if (!meta.enableServiceWorker) return;
|
||||||
|
|
||||||
if (typeof userId === 'string') {
|
if (typeof userId === 'string') {
|
||||||
userId = new mongo.ObjectID(userId);
|
userId = new mongo.ObjectID(userId);
|
||||||
|
|
|
@ -285,6 +285,27 @@ export const meta = {
|
||||||
'ja-JP': 'SMTPサーバのパスワード'
|
'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;
|
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({}, {
|
await Meta.update({}, {
|
||||||
$set: set
|
$set: set
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||||
cacheRemoteFiles: instance.cacheRemoteFiles,
|
cacheRemoteFiles: instance.cacheRemoteFiles,
|
||||||
enableRecaptcha: instance.enableRecaptcha,
|
enableRecaptcha: instance.enableRecaptcha,
|
||||||
recaptchaSiteKey: instance.recaptchaSiteKey,
|
recaptchaSiteKey: instance.recaptchaSiteKey,
|
||||||
swPublickey: null,
|
swPublickey: instance.swPublicKey,
|
||||||
bannerUrl: instance.bannerUrl,
|
bannerUrl: instance.bannerUrl,
|
||||||
errorImageUrl: instance.errorImageUrl,
|
errorImageUrl: instance.errorImageUrl,
|
||||||
maxNoteTextLength: instance.maxNoteTextLength,
|
maxNoteTextLength: instance.maxNoteTextLength,
|
||||||
|
@ -85,7 +85,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||||
twitter: instance.enableTwitterIntegration,
|
twitter: instance.enableTwitterIntegration,
|
||||||
github: instance.enableGithubIntegration,
|
github: instance.enableGithubIntegration,
|
||||||
discord: instance.enableDiscordIntegration,
|
discord: instance.enableDiscordIntegration,
|
||||||
serviceWorker: config.sw ? true : false,
|
serviceWorker: instance.enableServiceWorker,
|
||||||
userRecommendation: {
|
userRecommendation: {
|
||||||
external: instance.enableExternalUserRecommendation,
|
external: instance.enableExternalUserRecommendation,
|
||||||
engine: instance.externalUserRecommendationEngine,
|
engine: instance.externalUserRecommendationEngine,
|
||||||
|
@ -114,6 +114,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||||
response.smtpPort = instance.smtpPort;
|
response.smtpPort = instance.smtpPort;
|
||||||
response.smtpUser = instance.smtpUser;
|
response.smtpUser = instance.smtpUser;
|
||||||
response.smtpPass = instance.smtpPass;
|
response.smtpPass = instance.smtpPass;
|
||||||
|
response.swPrivateKey = instance.swPrivateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
res(response);
|
res(response);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import Subscription from '../../../../models/sw-subscription';
|
import Subscription from '../../../../models/sw-subscription';
|
||||||
import config from '../../../../config';
|
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
import fetchMeta from '../../../../misc/fetch-meta';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -31,10 +31,12 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||||
deletedAt: { $exists: false }
|
deletedAt: { $exists: false }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const instance = await fetchMeta();
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) {
|
||||||
return res({
|
return res({
|
||||||
state: 'already-subscribed',
|
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({
|
res({
|
||||||
state: 'subscribed',
|
state: 'subscribed',
|
||||||
key: config.sw.publicKey
|
key: instance.swPublicKey
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
Loading…
Reference in New Issue