mirror of
https://iceshrimp.dev/iceshrimp/iceshrimp
synced 2024-11-23 14:46:07 +09:00
[backend] Automatically generate vapid/web-push keys
Co-authored-by: Johann150 (563f3672a9
)
This commit is contained in:
parent
b53b7a8654
commit
f14b3cec97
@ -15,12 +15,6 @@ This document describes things you can do after successfully installing Iceshrim
|
|||||||
- Install [LibreTranslate](https://libretranslate.com/)
|
- Install [LibreTranslate](https://libretranslate.com/)
|
||||||
- Get an API URL and API key, copy and paste them into Control Panel > General > Libre Translate
|
- Get an API URL and API key, copy and paste them into Control Panel > General > Libre Translate
|
||||||
|
|
||||||
## Enabling push notifications
|
|
||||||
|
|
||||||
- Run `npx web-push generate-vapid-keys`
|
|
||||||
- Docker Compose users: `docker compose exec web npx web-push generate-vapid-keys`
|
|
||||||
- Put public and private keys into Control Panel > General > Service Worker
|
|
||||||
|
|
||||||
## Object Storage (S3)
|
## Object Storage (S3)
|
||||||
|
|
||||||
Recommended if using Docker
|
Recommended if using Docker
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||||
|
import push from 'web-push';
|
||||||
|
|
||||||
|
export class AutoGenerateVapidKeys1697216726757 implements MigrationInterface {
|
||||||
|
// Based on FoundKey's 1668374092227-forceEnablePush.js
|
||||||
|
name = 'AutoGenerateVapidKeys1697216726757';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
// set VAPID keys if not yet set
|
||||||
|
const { publicKey, privateKey } = push.generateVAPIDKeys();
|
||||||
|
await queryRunner.query(`UPDATE "meta" SET "swPublicKey" = $1, "swPrivateKey" = $2 WHERE "swPublicKey" IS NULL OR "swPrivateKey" IS NULL`, [publicKey, privateKey]);
|
||||||
|
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableServiceWorker"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "swPublicKey" SET NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "swPrivateKey" SET NOT NULL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "swPrivateKey" DROP NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "swPublicKey" DROP NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "enableServiceWorker" boolean NOT NULL DEFAULT false`);
|
||||||
|
// since VAPID keys are set and the service worker may have been enabled before, make sure it is now enabled
|
||||||
|
await queryRunner.query(`UPDATE "meta" SET "enableServiceWorker" = true`);
|
||||||
|
// can't unset the VAPID keys because we do not know if we set them in the migration
|
||||||
|
}
|
||||||
|
}
|
@ -337,22 +337,17 @@ export class Meta {
|
|||||||
})
|
})
|
||||||
public smtpPass: string | null;
|
public smtpPass: string | null;
|
||||||
|
|
||||||
@Column("boolean", {
|
@Column("varchar", {
|
||||||
default: false,
|
length: 128,
|
||||||
|
nullable: false,
|
||||||
})
|
})
|
||||||
public enableServiceWorker: boolean;
|
public swPublicKey: string;
|
||||||
|
|
||||||
@Column("varchar", {
|
@Column("varchar", {
|
||||||
length: 128,
|
length: 128,
|
||||||
nullable: true,
|
nullable: false,
|
||||||
})
|
})
|
||||||
public swPublicKey: string | null;
|
public swPrivateKey: string;
|
||||||
|
|
||||||
@Column("varchar", {
|
|
||||||
length: 128,
|
|
||||||
nullable: true,
|
|
||||||
})
|
|
||||||
public swPrivateKey: string | null;
|
|
||||||
|
|
||||||
@Column("boolean", {
|
@Column("boolean", {
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -156,11 +156,6 @@ export const meta = {
|
|||||||
optional: false,
|
optional: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
},
|
},
|
||||||
enableServiceWorker: {
|
|
||||||
type: "boolean",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
},
|
|
||||||
translatorAvailable: {
|
translatorAvailable: {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
optional: false,
|
optional: false,
|
||||||
@ -518,7 +513,6 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||||||
enableTwitterIntegration: instance.enableTwitterIntegration,
|
enableTwitterIntegration: instance.enableTwitterIntegration,
|
||||||
enableGithubIntegration: instance.enableGithubIntegration,
|
enableGithubIntegration: instance.enableGithubIntegration,
|
||||||
enableDiscordIntegration: instance.enableDiscordIntegration,
|
enableDiscordIntegration: instance.enableDiscordIntegration,
|
||||||
enableServiceWorker: instance.enableServiceWorker,
|
|
||||||
translatorAvailable:
|
translatorAvailable:
|
||||||
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
|
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
|
||||||
pinnedPages: instance.pinnedPages,
|
pinnedPages: instance.pinnedPages,
|
||||||
|
@ -148,7 +148,6 @@ export const paramDef = {
|
|||||||
smtpPort: { type: "integer", nullable: true },
|
smtpPort: { type: "integer", nullable: true },
|
||||||
smtpUser: { type: "string", nullable: true },
|
smtpUser: { type: "string", nullable: true },
|
||||||
smtpPass: { type: "string", nullable: true },
|
smtpPass: { type: "string", nullable: true },
|
||||||
enableServiceWorker: { type: "boolean" },
|
|
||||||
swPublicKey: { type: "string", nullable: true },
|
swPublicKey: { type: "string", nullable: true },
|
||||||
swPrivateKey: { type: "string", nullable: true },
|
swPrivateKey: { type: "string", nullable: true },
|
||||||
tosUrl: { type: "string", nullable: true },
|
tosUrl: { type: "string", nullable: true },
|
||||||
@ -463,10 +462,6 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||||||
set.errorImageUrl = ps.errorImageUrl;
|
set.errorImageUrl = ps.errorImageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.enableServiceWorker !== undefined) {
|
|
||||||
set.enableServiceWorker = ps.enableServiceWorker;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.swPublicKey !== undefined) {
|
if (ps.swPublicKey !== undefined) {
|
||||||
set.swPublicKey = ps.swPublicKey;
|
set.swPublicKey = ps.swPublicKey;
|
||||||
}
|
}
|
||||||
|
@ -266,11 +266,6 @@ export const meta = {
|
|||||||
optional: false,
|
optional: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
},
|
},
|
||||||
enableServiceWorker: {
|
|
||||||
type: "boolean",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
},
|
|
||||||
translatorAvailable: {
|
translatorAvailable: {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
optional: false,
|
optional: false,
|
||||||
@ -377,13 +372,13 @@ export const meta = {
|
|||||||
},
|
},
|
||||||
defaultReaction: {
|
defaultReaction: {
|
||||||
type: "string",
|
type: "string",
|
||||||
optional: "false",
|
optional: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
default: "⭐",
|
default: "⭐",
|
||||||
},
|
},
|
||||||
donationLink: {
|
donationLink: {
|
||||||
type: "string",
|
type: "string",
|
||||||
optional: "true",
|
optional: true,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -472,8 +467,6 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||||||
enableGithubIntegration: instance.enableGithubIntegration,
|
enableGithubIntegration: instance.enableGithubIntegration,
|
||||||
enableDiscordIntegration: instance.enableDiscordIntegration,
|
enableDiscordIntegration: instance.enableDiscordIntegration,
|
||||||
|
|
||||||
enableServiceWorker: instance.enableServiceWorker,
|
|
||||||
|
|
||||||
translatorAvailable:
|
translatorAvailable:
|
||||||
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
|
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
|
||||||
defaultReaction: instance.defaultReaction,
|
defaultReaction: instance.defaultReaction,
|
||||||
@ -515,7 +508,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||||||
twitter: instance.enableTwitterIntegration,
|
twitter: instance.enableTwitterIntegration,
|
||||||
github: instance.enableGithubIntegration,
|
github: instance.enableGithubIntegration,
|
||||||
discord: instance.enableDiscordIntegration,
|
discord: instance.enableDiscordIntegration,
|
||||||
serviceWorker: instance.enableServiceWorker,
|
serviceWorker: true,
|
||||||
postEditing: true,
|
postEditing: true,
|
||||||
postImports: instance.experimentalFeatures?.postImports || false,
|
postImports: instance.experimentalFeatures?.postImports || false,
|
||||||
miauth: true,
|
miauth: true,
|
||||||
|
@ -93,7 +93,6 @@ const nodeinfo2 = async () => {
|
|||||||
enableGithubIntegration: meta.enableGithubIntegration,
|
enableGithubIntegration: meta.enableGithubIntegration,
|
||||||
enableDiscordIntegration: meta.enableDiscordIntegration,
|
enableDiscordIntegration: meta.enableDiscordIntegration,
|
||||||
enableEmail: meta.enableEmail,
|
enableEmail: meta.enableEmail,
|
||||||
enableServiceWorker: meta.enableServiceWorker,
|
|
||||||
proxyAccountName: proxyAccount ? proxyAccount.username : null,
|
proxyAccountName: proxyAccount ? proxyAccount.username : null,
|
||||||
themeColor: meta.themeColor || "#31748f",
|
themeColor: meta.themeColor || "#31748f",
|
||||||
},
|
},
|
||||||
|
@ -47,13 +47,6 @@ export async function pushNotification<T extends keyof pushNotificationsTypes>(
|
|||||||
) {
|
) {
|
||||||
const meta = await fetchMeta();
|
const meta = await fetchMeta();
|
||||||
|
|
||||||
if (
|
|
||||||
!meta.enableServiceWorker ||
|
|
||||||
meta.swPublicKey == null ||
|
|
||||||
meta.swPrivateKey == null
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
|
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
|
||||||
push.setVapidDetails(config.url, meta.swPublicKey, meta.swPrivateKey);
|
push.setVapidDetails(config.url, meta.swPublicKey, meta.swPrivateKey);
|
||||||
|
|
||||||
|
@ -317,44 +317,6 @@
|
|||||||
</FormSplit>
|
</FormSplit>
|
||||||
</FormSection>
|
</FormSection>
|
||||||
|
|
||||||
<FormSection>
|
|
||||||
<template #label>ServiceWorker</template>
|
|
||||||
|
|
||||||
<FormSwitch
|
|
||||||
v-model="enableServiceWorker"
|
|
||||||
class="_formBlock"
|
|
||||||
>
|
|
||||||
<template #label>{{
|
|
||||||
i18n.ts.enableServiceworker
|
|
||||||
}}</template>
|
|
||||||
<template #caption>{{
|
|
||||||
i18n.ts.serviceworkerInfo
|
|
||||||
}}</template>
|
|
||||||
</FormSwitch>
|
|
||||||
|
|
||||||
<template v-if="enableServiceWorker">
|
|
||||||
<FormInput
|
|
||||||
v-model="swPublicKey"
|
|
||||||
class="_formBlock"
|
|
||||||
>
|
|
||||||
<template #prefix
|
|
||||||
><i class="ph-key ph-bold ph-lg"></i
|
|
||||||
></template>
|
|
||||||
<template #label>Public key</template>
|
|
||||||
</FormInput>
|
|
||||||
|
|
||||||
<FormInput
|
|
||||||
v-model="swPrivateKey"
|
|
||||||
class="_formBlock"
|
|
||||||
>
|
|
||||||
<template #prefix
|
|
||||||
><i class="ph-key ph-bold ph-lg"></i
|
|
||||||
></template>
|
|
||||||
<template #label>Private key</template>
|
|
||||||
</FormInput>
|
|
||||||
</template>
|
|
||||||
</FormSection>
|
|
||||||
|
|
||||||
<FormSection>
|
<FormSection>
|
||||||
<template #label>Server Performance</template>
|
<template #label>Server Performance</template>
|
||||||
<FormSwitch
|
<FormSwitch
|
||||||
@ -467,9 +429,6 @@ let localDriveCapacityMb: any = $ref(0);
|
|||||||
let remoteDriveCapacityMb: any = $ref(0);
|
let remoteDriveCapacityMb: any = $ref(0);
|
||||||
let enableRegistration: boolean = $ref(false);
|
let enableRegistration: boolean = $ref(false);
|
||||||
let emailRequiredForSignup: boolean = $ref(false);
|
let emailRequiredForSignup: boolean = $ref(false);
|
||||||
let enableServiceWorker: boolean = $ref(false);
|
|
||||||
let swPublicKey: any = $ref(null);
|
|
||||||
let swPrivateKey: any = $ref(null);
|
|
||||||
let deeplAuthKey: string = $ref("");
|
let deeplAuthKey: string = $ref("");
|
||||||
let deeplIsPro: boolean = $ref(false);
|
let deeplIsPro: boolean = $ref(false);
|
||||||
let libreTranslateApiUrl: string = $ref("");
|
let libreTranslateApiUrl: string = $ref("");
|
||||||
@ -507,9 +466,6 @@ async function init() {
|
|||||||
remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
|
remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
|
||||||
enableRegistration = !meta.disableRegistration;
|
enableRegistration = !meta.disableRegistration;
|
||||||
emailRequiredForSignup = meta.emailRequiredForSignup;
|
emailRequiredForSignup = meta.emailRequiredForSignup;
|
||||||
enableServiceWorker = meta.enableServiceWorker;
|
|
||||||
swPublicKey = meta.swPublickey;
|
|
||||||
swPrivateKey = meta.swPrivateKey;
|
|
||||||
deeplAuthKey = meta.deeplAuthKey;
|
deeplAuthKey = meta.deeplAuthKey;
|
||||||
deeplIsPro = meta.deeplIsPro;
|
deeplIsPro = meta.deeplIsPro;
|
||||||
libreTranslateApiUrl = meta.libreTranslateApiUrl;
|
libreTranslateApiUrl = meta.libreTranslateApiUrl;
|
||||||
@ -554,9 +510,6 @@ function save() {
|
|||||||
remoteDriveCapacityMb: parseInt(remoteDriveCapacityMb, 10),
|
remoteDriveCapacityMb: parseInt(remoteDriveCapacityMb, 10),
|
||||||
disableRegistration: !enableRegistration,
|
disableRegistration: !enableRegistration,
|
||||||
emailRequiredForSignup,
|
emailRequiredForSignup,
|
||||||
enableServiceWorker,
|
|
||||||
swPublicKey,
|
|
||||||
swPrivateKey,
|
|
||||||
deeplAuthKey,
|
deeplAuthKey,
|
||||||
deeplIsPro,
|
deeplIsPro,
|
||||||
libreTranslateApiUrl,
|
libreTranslateApiUrl,
|
||||||
|
@ -299,7 +299,6 @@ export type LiteInstanceMetadata = {
|
|||||||
enableTwitterIntegration: boolean;
|
enableTwitterIntegration: boolean;
|
||||||
enableGithubIntegration: boolean;
|
enableGithubIntegration: boolean;
|
||||||
enableDiscordIntegration: boolean;
|
enableDiscordIntegration: boolean;
|
||||||
enableServiceWorker: boolean;
|
|
||||||
searchEngine: string;
|
searchEngine: string;
|
||||||
emojis: CustomEmoji[];
|
emojis: CustomEmoji[];
|
||||||
images: {
|
images: {
|
||||||
|
Loading…
Reference in New Issue
Block a user