[backend] Automatically generate vapid/web-push keys

Co-authored-by: Johann150 (563f3672a9)
This commit is contained in:
Laura Hausmann 2023-10-13 19:17:30 +02:00
parent b53b7a8654
commit f14b3cec97
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
10 changed files with 35 additions and 94 deletions

View file

@ -15,12 +15,6 @@ This document describes things you can do after successfully installing Iceshrim
- Install [LibreTranslate](https://libretranslate.com/)
- 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)
Recommended if using Docker

View file

@ -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
}
}

View file

@ -337,22 +337,17 @@ export class Meta {
})
public smtpPass: string | null;
@Column("boolean", {
default: false,
@Column("varchar", {
length: 128,
nullable: false,
})
public enableServiceWorker: boolean;
public swPublicKey: string;
@Column("varchar", {
length: 128,
nullable: true,
nullable: false,
})
public swPublicKey: string | null;
@Column("varchar", {
length: 128,
nullable: true,
})
public swPrivateKey: string | null;
public swPrivateKey: string;
@Column("boolean", {
default: false,

View file

@ -156,11 +156,6 @@ export const meta = {
optional: false,
nullable: false,
},
enableServiceWorker: {
type: "boolean",
optional: false,
nullable: false,
},
translatorAvailable: {
type: "boolean",
optional: false,
@ -518,7 +513,6 @@ export default define(meta, paramDef, async (ps, me) => {
enableTwitterIntegration: instance.enableTwitterIntegration,
enableGithubIntegration: instance.enableGithubIntegration,
enableDiscordIntegration: instance.enableDiscordIntegration,
enableServiceWorker: instance.enableServiceWorker,
translatorAvailable:
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
pinnedPages: instance.pinnedPages,

View file

@ -148,7 +148,6 @@ export const paramDef = {
smtpPort: { type: "integer", nullable: true },
smtpUser: { type: "string", nullable: true },
smtpPass: { type: "string", nullable: true },
enableServiceWorker: { type: "boolean" },
swPublicKey: { type: "string", nullable: true },
swPrivateKey: { 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;
}
if (ps.enableServiceWorker !== undefined) {
set.enableServiceWorker = ps.enableServiceWorker;
}
if (ps.swPublicKey !== undefined) {
set.swPublicKey = ps.swPublicKey;
}

View file

@ -266,11 +266,6 @@ export const meta = {
optional: false,
nullable: false,
},
enableServiceWorker: {
type: "boolean",
optional: false,
nullable: false,
},
translatorAvailable: {
type: "boolean",
optional: false,
@ -377,13 +372,13 @@ export const meta = {
},
defaultReaction: {
type: "string",
optional: "false",
optional: false,
nullable: false,
default: "⭐",
},
donationLink: {
type: "string",
optional: "true",
optional: true,
nullable: true,
},
},
@ -472,8 +467,6 @@ export default define(meta, paramDef, async (ps, me) => {
enableGithubIntegration: instance.enableGithubIntegration,
enableDiscordIntegration: instance.enableDiscordIntegration,
enableServiceWorker: instance.enableServiceWorker,
translatorAvailable:
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
defaultReaction: instance.defaultReaction,
@ -515,7 +508,7 @@ export default define(meta, paramDef, async (ps, me) => {
twitter: instance.enableTwitterIntegration,
github: instance.enableGithubIntegration,
discord: instance.enableDiscordIntegration,
serviceWorker: instance.enableServiceWorker,
serviceWorker: true,
postEditing: true,
postImports: instance.experimentalFeatures?.postImports || false,
miauth: true,

View file

@ -93,7 +93,6 @@ const nodeinfo2 = async () => {
enableGithubIntegration: meta.enableGithubIntegration,
enableDiscordIntegration: meta.enableDiscordIntegration,
enableEmail: meta.enableEmail,
enableServiceWorker: meta.enableServiceWorker,
proxyAccountName: proxyAccount ? proxyAccount.username : null,
themeColor: meta.themeColor || "#31748f",
},

View file

@ -47,13 +47,6 @@ export async function pushNotification<T extends keyof pushNotificationsTypes>(
) {
const meta = await fetchMeta();
if (
!meta.enableServiceWorker ||
meta.swPublicKey == null ||
meta.swPrivateKey == null
)
return;
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
push.setVapidDetails(config.url, meta.swPublicKey, meta.swPrivateKey);

View file

@ -317,44 +317,6 @@
</FormSplit>
</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>
<template #label>Server Performance</template>
<FormSwitch
@ -467,9 +429,6 @@ let localDriveCapacityMb: any = $ref(0);
let remoteDriveCapacityMb: any = $ref(0);
let enableRegistration: 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 deeplIsPro: boolean = $ref(false);
let libreTranslateApiUrl: string = $ref("");
@ -507,9 +466,6 @@ async function init() {
remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
enableRegistration = !meta.disableRegistration;
emailRequiredForSignup = meta.emailRequiredForSignup;
enableServiceWorker = meta.enableServiceWorker;
swPublicKey = meta.swPublickey;
swPrivateKey = meta.swPrivateKey;
deeplAuthKey = meta.deeplAuthKey;
deeplIsPro = meta.deeplIsPro;
libreTranslateApiUrl = meta.libreTranslateApiUrl;
@ -554,9 +510,6 @@ function save() {
remoteDriveCapacityMb: parseInt(remoteDriveCapacityMb, 10),
disableRegistration: !enableRegistration,
emailRequiredForSignup,
enableServiceWorker,
swPublicKey,
swPrivateKey,
deeplAuthKey,
deeplIsPro,
libreTranslateApiUrl,

View file

@ -299,7 +299,6 @@ export type LiteInstanceMetadata = {
enableTwitterIntegration: boolean;
enableGithubIntegration: boolean;
enableDiscordIntegration: boolean;
enableServiceWorker: boolean;
searchEngine: string;
emojis: CustomEmoji[];
images: {