forked from FoundKeyGang/FoundKey
Resolve #4928
This commit is contained in:
parent
3d8bbedf1b
commit
3f5b96bf62
12 changed files with 370 additions and 160 deletions
|
@ -6,8 +6,6 @@ mongodb:
|
||||||
db: misskey
|
db: misskey
|
||||||
user: syuilo
|
user: syuilo
|
||||||
pass: ''
|
pass: ''
|
||||||
drive:
|
|
||||||
storage: 'db'
|
|
||||||
redis:
|
redis:
|
||||||
host: localhost
|
host: localhost
|
||||||
port: 6379
|
port: 6379
|
||||||
|
|
|
@ -6,8 +6,6 @@ mongodb:
|
||||||
db: test-misskey
|
db: test-misskey
|
||||||
user: admin
|
user: admin
|
||||||
pass: ''
|
pass: ''
|
||||||
drive:
|
|
||||||
storage: 'db'
|
|
||||||
# __REDIS__
|
# __REDIS__
|
||||||
redis:
|
redis:
|
||||||
host: localhost
|
host: localhost
|
||||||
|
|
|
@ -78,61 +78,6 @@ redis:
|
||||||
# port: 9200
|
# port: 9200
|
||||||
# pass: null
|
# pass: null
|
||||||
|
|
||||||
# ┌────────────────────────────────────┐
|
|
||||||
#───┘ File storage (Drive) configuration └──────────────────────
|
|
||||||
|
|
||||||
drive:
|
|
||||||
storage: 'fs'
|
|
||||||
|
|
||||||
# OR
|
|
||||||
|
|
||||||
#drive:
|
|
||||||
# storage: 'minio'
|
|
||||||
# bucket:
|
|
||||||
# prefix:
|
|
||||||
# config:
|
|
||||||
# endPoint:
|
|
||||||
# port:
|
|
||||||
# useSSL:
|
|
||||||
# accessKey:
|
|
||||||
# secretKey:
|
|
||||||
|
|
||||||
# S3/GCS example
|
|
||||||
#
|
|
||||||
# * Replace <endpoint> to
|
|
||||||
# S3: see https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
|
|
||||||
# GCS: use 'storage.googleapis.com'
|
|
||||||
#
|
|
||||||
# * Replace <region> to
|
|
||||||
# S3: see https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
|
|
||||||
# GCS: not needed (just delete the region line)
|
|
||||||
#
|
|
||||||
#drive:
|
|
||||||
# storage: 'minio'
|
|
||||||
# bucket: bucket-name
|
|
||||||
# prefix: files
|
|
||||||
# baseUrl: https://bucket-name.<endpoint>
|
|
||||||
# config:
|
|
||||||
# endPoint: <endpoint>
|
|
||||||
# region: <region>
|
|
||||||
# useSSL: true
|
|
||||||
# accessKey: XXX
|
|
||||||
# secretKey: YYY
|
|
||||||
|
|
||||||
# S3/GCS example (with CDN, custom domain)
|
|
||||||
#
|
|
||||||
#drive:
|
|
||||||
# storage: 'minio'
|
|
||||||
# bucket: drive.example.com
|
|
||||||
# prefix: files
|
|
||||||
# baseUrl: https://drive.example.com
|
|
||||||
# config:
|
|
||||||
# endPoint: <endpoint>
|
|
||||||
# region: <region>
|
|
||||||
# useSSL: true
|
|
||||||
# accessKey: XXX
|
|
||||||
# secretKey: YYY
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
# ┌───────────────┐
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
#───┘ ID generation └───────────────────────────────────────────
|
||||||
|
|
||||||
|
|
|
@ -1232,6 +1232,19 @@ admin/views/instance.vue:
|
||||||
advanced-config: "その他の設定"
|
advanced-config: "その他の設定"
|
||||||
note-and-tl: "投稿とタイムライン"
|
note-and-tl: "投稿とタイムライン"
|
||||||
drive-config: "ドライブの設定"
|
drive-config: "ドライブの設定"
|
||||||
|
use-object-storage: "オブジェクトストレージを使用する"
|
||||||
|
object-storage-base-url: "URL"
|
||||||
|
object-storage-bucket: "バケット名"
|
||||||
|
object-storage-prefix: "プレフィックス"
|
||||||
|
object-storage-endpoint: "エンドポイント"
|
||||||
|
object-storage-region: "リージョン"
|
||||||
|
object-storage-port: "ポート"
|
||||||
|
object-storage-access-key: "アクセスキー"
|
||||||
|
object-storage-secret-key: "シークレットキー"
|
||||||
|
object-storage-use-ssl: "SSLを使用"
|
||||||
|
object-storage-s3-info: "Amazon S3をオブジェクトストレージとして使用する場合の「エンドポイント」と「リージョン」の設定については{0}をご確認ください。"
|
||||||
|
object-storage-s3-info-here: "こちら"
|
||||||
|
object-storage-gcs-info: "Google Cloud Storageをオブジェクトストレージとして使用する場合、「エンドポイント」は storage.googleapis.com に設定し、「リージョン」は空欄にします。"
|
||||||
cache-remote-files: "リモートのファイルをキャッシュする"
|
cache-remote-files: "リモートのファイルをキャッシュする"
|
||||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
|
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
|
||||||
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
||||||
|
|
31
migration/1557932705754-ObjectStorageSetting.ts
Normal file
31
migration/1557932705754-ObjectStorageSetting.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||||
|
|
||||||
|
export class ObjectStorageSetting1557932705754 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "useObjectStorage" boolean NOT NULL DEFAULT false`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBucket" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePrefix" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBaseUrl" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageEndpoint" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageRegion" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageAccessKey" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSecretKey" character varying(512)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePort" integer`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseSSL" boolean NOT NULL DEFAULT true`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseSSL"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePort"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSecretKey"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageAccessKey"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageRegion"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageEndpoint"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBaseUrl"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePrefix"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBucket"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "useObjectStorage"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -53,6 +53,32 @@
|
||||||
|
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<template #title><fa icon="cloud"/> {{ $t('drive-config') }}</template>
|
<template #title><fa icon="cloud"/> {{ $t('drive-config') }}</template>
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="useObjectStorage">{{ $t('use-object-storage') }}</ui-switch>
|
||||||
|
<template v-if="useObjectStorage">
|
||||||
|
<ui-info>
|
||||||
|
<i18n path="object-storage-s3-info">
|
||||||
|
<a href="https://docs.aws.amazon.com/general/latest/gr/rande.html" target="_blank">{{ $t('object-storage-s3-info-here') }}</a>
|
||||||
|
</i18n>
|
||||||
|
</ui-info>
|
||||||
|
<ui-info>{{ $t('object-storage-gcs-info') }}</ui-info>
|
||||||
|
<ui-input v-model="objectStorageBaseUrl" :disabled="!useObjectStorage">{{ $t('object-storage-base-url') }}</ui-input>
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input v-model="objectStorageBucket" :disabled="!useObjectStorage">{{ $t('object-storage-bucket') }}</ui-input>
|
||||||
|
<ui-input v-model="objectStoragePrefix" :disabled="!useObjectStorage">{{ $t('object-storage-prefix') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-input v-model="objectStorageEndpoint" :disabled="!useObjectStorage">{{ $t('object-storage-endpoint') }}</ui-input>
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input v-model="objectStorageRegion" :disabled="!useObjectStorage">{{ $t('object-storage-region') }}</ui-input>
|
||||||
|
<ui-input v-model="objectStoragePort" type="number" :disabled="!useObjectStorage">{{ $t('object-storage-port') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input v-model="objectStorageAccessKey" :disabled="!useObjectStorage"><template #icon><fa icon="key"/></template>{{ $t('object-storage-access-key') }}</ui-input>
|
||||||
|
<ui-input v-model="objectStorageSecretKey" :disabled="!useObjectStorage"><template #icon><fa icon="key"/></template>{{ $t('object-storage-secret-key') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-switch v-model="objectStorageUseSSL" :disabled="!useObjectStorage">{{ $t('object-storage-use-ssl') }}</ui-switch>
|
||||||
|
</template>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<template #desc>{{ $t('cache-remote-files-desc') }}</template></ui-switch>
|
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<template #desc>{{ $t('cache-remote-files-desc') }}</template></ui-switch>
|
||||||
</section>
|
</section>
|
||||||
|
@ -65,69 +91,6 @@
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
|
|
||||||
<ui-card>
|
|
||||||
<template #title><fa :icon="farEnvelope"/> {{ $t('email-config') }}</template>
|
|
||||||
<section>
|
|
||||||
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<template #desc>{{ $t('email-config-info') }}</template></ui-switch>
|
|
||||||
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
|
|
||||||
<ui-horizon-group inputs>
|
|
||||||
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
|
|
||||||
<ui-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtp-port') }}</ui-input>
|
|
||||||
</ui-horizon-group>
|
|
||||||
<ui-switch v-model="smtpAuth">{{ $t('smtp-auth') }}</ui-switch>
|
|
||||||
<ui-horizon-group inputs>
|
|
||||||
<ui-input v-model="smtpUser" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-user') }}</ui-input>
|
|
||||||
<ui-input v-model="smtpPass" type="password" :with-password-toggle="true" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-pass') }}</ui-input>
|
|
||||||
</ui-horizon-group>
|
|
||||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<template #desc>{{ $t('smtp-secure-info') }}</template></ui-switch>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
|
||||||
</section>
|
|
||||||
</ui-card>
|
|
||||||
|
|
||||||
<ui-card>
|
|
||||||
<template #title><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</template>
|
|
||||||
<section>
|
|
||||||
<ui-info>{{ $t('proxy-account-info') }}</ui-info>
|
|
||||||
<ui-input v-model="proxyAccount"><template #prefix>@</template>{{ $t('proxy-account-username') }}<template #desc>{{ $t('proxy-account-username-desc') }}</template></ui-input>
|
|
||||||
<ui-info warn>{{ $t('proxy-account-warn') }}</ui-info>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
|
||||||
</section>
|
|
||||||
</ui-card>
|
|
||||||
|
|
||||||
<ui-card>
|
|
||||||
<template #title><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</template>
|
|
||||||
<section>
|
|
||||||
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<template #desc>{{ $t('serviceworker-info') }}</template></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"><template #icon><fa icon="key"/></template>{{ $t('vapid-publickey') }}</ui-input>
|
|
||||||
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-privatekey') }}</ui-input>
|
|
||||||
</ui-horizon-group>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
|
||||||
</section>
|
|
||||||
</ui-card>
|
|
||||||
|
|
||||||
<ui-card>
|
|
||||||
<template #title><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</template>
|
|
||||||
<section class="fit-bottom">
|
|
||||||
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
|
||||||
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
|
||||||
<ui-horizon-group inputs>
|
|
||||||
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
|
|
||||||
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
|
|
||||||
</ui-horizon-group>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
|
||||||
</section>
|
|
||||||
</ui-card>
|
|
||||||
|
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<template #title><fa :icon="faThumbtack"/> {{ $t('pinned-users') }}</template>
|
<template #title><fa :icon="faThumbtack"/> {{ $t('pinned-users') }}</template>
|
||||||
<section class="fit-top">
|
<section class="fit-top">
|
||||||
|
@ -138,34 +101,109 @@
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card>
|
||||||
|
<template #title><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</template>
|
||||||
|
<section>
|
||||||
|
<ui-info>{{ $t('proxy-account-info') }}</ui-info>
|
||||||
|
<ui-input v-model="proxyAccount"><template #prefix>@</template>{{ $t('proxy-account-username') }}<template #desc>{{ $t('proxy-account-username-desc') }}</template></ui-input>
|
||||||
|
<ui-info warn>{{ $t('proxy-account-warn') }}</ui-info>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card>
|
||||||
|
<template #title><fa :icon="farEnvelope"/> {{ $t('email-config') }}</template>
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<template #desc>{{ $t('email-config-info') }}</template></ui-switch>
|
||||||
|
<template v-if="enableEmail">
|
||||||
|
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
|
||||||
|
<ui-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtp-port') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-switch v-model="smtpAuth">{{ $t('smtp-auth') }}</ui-switch>
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input v-model="smtpUser" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-user') }}</ui-input>
|
||||||
|
<ui-input v-model="smtpPass" type="password" :with-password-toggle="true" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-pass') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<template #desc>{{ $t('smtp-secure-info') }}</template></ui-switch>
|
||||||
|
</template>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card>
|
||||||
|
<template #title><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</template>
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<template #desc>{{ $t('serviceworker-info') }}</template></ui-switch>
|
||||||
|
<template v-if="enableServiceWorker">
|
||||||
|
<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"><template #icon><fa icon="key"/></template>{{ $t('vapid-publickey') }}</ui-input>
|
||||||
|
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-privatekey') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
</template>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card>
|
||||||
|
<template #title><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</template>
|
||||||
|
<section :class="enableRecaptcha ? 'fit-bottom' : ''">
|
||||||
|
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
||||||
|
<template v-if="enableRecaptcha">
|
||||||
|
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
|
||||||
|
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
</template>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<template #title><fa :icon="faShieldAlt"/> {{ $t('external-service-integration-config') }}</template>
|
<template #title><fa :icon="faShieldAlt"/> {{ $t('external-service-integration-config') }}</template>
|
||||||
<section>
|
<section>
|
||||||
<header><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</header>
|
<header><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</header>
|
||||||
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
|
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
|
||||||
|
<template v-if="enableTwitterIntegration">
|
||||||
<ui-horizon-group>
|
<ui-horizon-group>
|
||||||
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
||||||
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
||||||
|
</template>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<header><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</header>
|
<header><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</header>
|
||||||
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
|
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
|
||||||
|
<template v-if="enableGithubIntegration">
|
||||||
<ui-horizon-group>
|
<ui-horizon-group>
|
||||||
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-id') }}</ui-input>
|
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-id') }}</ui-input>
|
||||||
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-secret') }}</ui-input>
|
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-secret') }}</ui-input>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
||||||
|
</template>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<header><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</header>
|
<header><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</header>
|
||||||
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
||||||
|
<template v-if="enableDiscordIntegration">
|
||||||
<ui-horizon-group>
|
<ui-horizon-group>
|
||||||
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-id') }}</ui-input>
|
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-id') }}</ui-input>
|
||||||
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-secret') }}</ui-input>
|
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-secret') }}</ui-input>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
||||||
|
</template>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
|
@ -261,6 +299,16 @@ export default Vue.extend({
|
||||||
swPrivateKey: null,
|
swPrivateKey: null,
|
||||||
pinnedUsers: '',
|
pinnedUsers: '',
|
||||||
hiddenTags: '',
|
hiddenTags: '',
|
||||||
|
useObjectStorage: false,
|
||||||
|
objectStorageBaseUrl: null,
|
||||||
|
objectStorageBucket: null,
|
||||||
|
objectStoragePrefix: null,
|
||||||
|
objectStorageEndpoint: null,
|
||||||
|
objectStorageRegion: null,
|
||||||
|
objectStoragePort: null,
|
||||||
|
objectStorageAccessKey: null,
|
||||||
|
objectStorageSecretKey: null,
|
||||||
|
objectStorageUseSSL: false,
|
||||||
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt, faThumbtack, faPencilAlt, faSave, faHashtag
|
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt, faThumbtack, faPencilAlt, faSave, faHashtag
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -315,6 +363,16 @@ export default Vue.extend({
|
||||||
this.swPrivateKey = meta.swPrivateKey;
|
this.swPrivateKey = meta.swPrivateKey;
|
||||||
this.pinnedUsers = meta.pinnedUsers.join('\n');
|
this.pinnedUsers = meta.pinnedUsers.join('\n');
|
||||||
this.hiddenTags = meta.hiddenTags.join('\n');
|
this.hiddenTags = meta.hiddenTags.join('\n');
|
||||||
|
this.useObjectStorage = meta.useObjectStorage;
|
||||||
|
this.objectStorageBaseUrl = meta.objectStorageBaseUrl;
|
||||||
|
this.objectStorageBucket = meta.objectStorageBucket;
|
||||||
|
this.objectStoragePrefix = meta.objectStoragePrefix;
|
||||||
|
this.objectStorageEndpoint = meta.objectStorageEndpoint;
|
||||||
|
this.objectStorageRegion = meta.objectStorageRegion;
|
||||||
|
this.objectStoragePort = meta.objectStoragePort;
|
||||||
|
this.objectStorageAccessKey = meta.objectStorageAccessKey;
|
||||||
|
this.objectStorageSecretKey = meta.objectStorageSecretKey;
|
||||||
|
this.objectStorageUseSSL = meta.objectStorageUseSSL;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -382,6 +440,16 @@ export default Vue.extend({
|
||||||
swPrivateKey: this.swPrivateKey,
|
swPrivateKey: this.swPrivateKey,
|
||||||
pinnedUsers: this.pinnedUsers.split('\n'),
|
pinnedUsers: this.pinnedUsers.split('\n'),
|
||||||
hiddenTags: this.hiddenTags.split('\n'),
|
hiddenTags: this.hiddenTags.split('\n'),
|
||||||
|
useObjectStorage: this.useObjectStorage,
|
||||||
|
objectStorageBaseUrl: this.objectStorageBaseUrl ? this.objectStorageBaseUrl : null,
|
||||||
|
objectStorageBucket: this.objectStorageBucket ? this.objectStorageBucket : null,
|
||||||
|
objectStoragePrefix: this.objectStoragePrefix ? this.objectStoragePrefix : null,
|
||||||
|
objectStorageEndpoint: this.objectStorageEndpoint ? this.objectStorageEndpoint : null,
|
||||||
|
objectStorageRegion: this.objectStorageRegion ? this.objectStorageRegion : null,
|
||||||
|
objectStoragePort: this.objectStoragePort ? this.objectStoragePort : null,
|
||||||
|
objectStorageAccessKey: this.objectStorageAccessKey ? this.objectStorageAccessKey : null,
|
||||||
|
objectStorageSecretKey: this.objectStorageSecretKey ? this.objectStorageSecretKey : null,
|
||||||
|
objectStorageUseSSL: this.objectStorageUseSSL,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$root.dialog({
|
this.$root.dialog({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
|
|
@ -27,13 +27,6 @@ export type Source = {
|
||||||
port: number;
|
port: number;
|
||||||
pass: string;
|
pass: string;
|
||||||
};
|
};
|
||||||
drive?: {
|
|
||||||
storage: string;
|
|
||||||
bucket?: string;
|
|
||||||
prefix?: string;
|
|
||||||
baseUrl?: string;
|
|
||||||
config?: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
autoAdmin?: boolean;
|
autoAdmin?: boolean;
|
||||||
|
|
||||||
|
|
|
@ -288,4 +288,61 @@ export class Meta {
|
||||||
nullable: true
|
nullable: true
|
||||||
})
|
})
|
||||||
public feedbackUrl: string | null;
|
public feedbackUrl: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public useObjectStorage: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStorageBucket: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStoragePrefix: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStorageBaseUrl: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStorageEndpoint: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStorageRegion: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStorageAccessKey: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStorageSecretKey: string | null;
|
||||||
|
|
||||||
|
@Column('integer', {
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
public objectStoragePort: number | null;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
|
public objectStorageUseSSL: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,7 +357,47 @@ export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
'ja-JP': 'フィードバックのURL'
|
'ja-JP': 'フィードバックのURL'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
useObjectStorage: {
|
||||||
|
validator: $.optional.bool
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageBaseUrl: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageBucket: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStoragePrefix: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageEndpoint: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageRegion: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStoragePort: {
|
||||||
|
validator: $.optional.nullable.num
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageAccessKey: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageSecretKey: {
|
||||||
|
validator: $.optional.nullable.str
|
||||||
|
},
|
||||||
|
|
||||||
|
objectStorageUseSSL: {
|
||||||
|
validator: $.optional.bool
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -560,6 +600,46 @@ export default define(meta, async (ps) => {
|
||||||
set.feedbackUrl = ps.feedbackUrl;
|
set.feedbackUrl = ps.feedbackUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.useObjectStorage !== undefined) {
|
||||||
|
set.useObjectStorage = ps.useObjectStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageBaseUrl !== undefined) {
|
||||||
|
set.objectStorageBaseUrl = ps.objectStorageBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageBucket !== undefined) {
|
||||||
|
set.objectStorageBucket = ps.objectStorageBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStoragePrefix !== undefined) {
|
||||||
|
set.objectStoragePrefix = ps.objectStoragePrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageEndpoint !== undefined) {
|
||||||
|
set.objectStorageEndpoint = ps.objectStorageEndpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageRegion !== undefined) {
|
||||||
|
set.objectStorageRegion = ps.objectStorageRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStoragePort !== undefined) {
|
||||||
|
set.objectStoragePort = ps.objectStoragePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageAccessKey !== undefined) {
|
||||||
|
set.objectStorageAccessKey = ps.objectStorageAccessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageSecretKey !== undefined) {
|
||||||
|
set.objectStorageSecretKey = ps.objectStorageSecretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.objectStorageUseSSL !== undefined) {
|
||||||
|
set.objectStorageUseSSL = ps.objectStorageUseSSL;
|
||||||
|
}
|
||||||
|
|
||||||
await getConnection().transaction(async transactionalEntityManager => {
|
await getConnection().transaction(async transactionalEntityManager => {
|
||||||
const meta = await transactionalEntityManager.findOne(Meta, {
|
const meta = await transactionalEntityManager.findOne(Meta, {
|
||||||
order: {
|
order: {
|
||||||
|
|
|
@ -153,7 +153,7 @@ export default define(meta, async (ps, me) => {
|
||||||
globalTimeLine: !instance.disableGlobalTimeline,
|
globalTimeLine: !instance.disableGlobalTimeline,
|
||||||
elasticsearch: config.elasticsearch ? true : false,
|
elasticsearch: config.elasticsearch ? true : false,
|
||||||
recaptcha: instance.enableRecaptcha,
|
recaptcha: instance.enableRecaptcha,
|
||||||
objectStorage: config.drive && config.drive.storage === 'minio',
|
objectStorage: instance.useObjectStorage,
|
||||||
twitter: instance.enableTwitterIntegration,
|
twitter: instance.enableTwitterIntegration,
|
||||||
github: instance.enableGithubIntegration,
|
github: instance.enableGithubIntegration,
|
||||||
discord: instance.enableDiscordIntegration,
|
discord: instance.enableDiscordIntegration,
|
||||||
|
@ -182,6 +182,16 @@ export default define(meta, async (ps, me) => {
|
||||||
response.smtpUser = instance.smtpUser;
|
response.smtpUser = instance.smtpUser;
|
||||||
response.smtpPass = instance.smtpPass;
|
response.smtpPass = instance.smtpPass;
|
||||||
response.swPrivateKey = instance.swPrivateKey;
|
response.swPrivateKey = instance.swPrivateKey;
|
||||||
|
response.useObjectStorage = instance.useObjectStorage;
|
||||||
|
response.objectStorageBaseUrl = instance.objectStorageBaseUrl;
|
||||||
|
response.objectStorageBucket = instance.objectStorageBucket;
|
||||||
|
response.objectStoragePrefix = instance.objectStoragePrefix;
|
||||||
|
response.objectStorageEndpoint = instance.objectStorageEndpoint;
|
||||||
|
response.objectStorageRegion = instance.objectStorageRegion;
|
||||||
|
response.objectStoragePort = instance.objectStoragePort;
|
||||||
|
response.objectStorageAccessKey = instance.objectStorageAccessKey;
|
||||||
|
response.objectStorageSecretKey = instance.objectStorageSecretKey;
|
||||||
|
response.objectStorageUseSSL = instance.objectStorageUseSSL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import * as sharp from 'sharp';
|
||||||
|
|
||||||
import { publishMainStream, publishDriveStream } from '../stream';
|
import { publishMainStream, publishDriveStream } from '../stream';
|
||||||
import delFile from './delete-file';
|
import delFile from './delete-file';
|
||||||
import config from '../../config';
|
|
||||||
import { fetchMeta } from '../../misc/fetch-meta';
|
import { fetchMeta } from '../../misc/fetch-meta';
|
||||||
import { GenerateVideoThumbnail } from './generate-video-thumbnail';
|
import { GenerateVideoThumbnail } from './generate-video-thumbnail';
|
||||||
import { driveLogger } from './logger';
|
import { driveLogger } from './logger';
|
||||||
|
@ -37,7 +36,9 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
|
||||||
// thunbnail, webpublic を必要なら生成
|
// thunbnail, webpublic を必要なら生成
|
||||||
const alts = await generateAlts(path, type, !file.uri);
|
const alts = await generateAlts(path, type, !file.uri);
|
||||||
|
|
||||||
if (config.drive && config.drive.storage == 'minio') {
|
const meta = await fetchMeta();
|
||||||
|
|
||||||
|
if (meta.useObjectStorage) {
|
||||||
//#region ObjectStorage params
|
//#region ObjectStorage params
|
||||||
let [ext] = (name.match(/\.([a-zA-Z0-9_-]+)$/) || ['']);
|
let [ext] = (name.match(/\.([a-zA-Z0-9_-]+)$/) || ['']);
|
||||||
|
|
||||||
|
@ -47,11 +48,11 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
|
||||||
if (type === 'image/webp') ext = '.webp';
|
if (type === 'image/webp') ext = '.webp';
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseUrl = config.drive.baseUrl
|
const baseUrl = meta.objectStorageBaseUrl
|
||||||
|| `${ config.drive.config.useSSL ? 'https' : 'http' }://${ config.drive.config.endPoint }${ config.drive.config.port ? `:${config.drive.config.port}` : '' }/${ config.drive.bucket }`;
|
|| `${ meta.objectStorageUseSSL ? 'https' : 'http' }://${ meta.objectStorageEndpoint }${ meta.objectStoragePort ? `:${meta.objectStoragePort}` : '' }/${ meta.objectStorageBucket }`;
|
||||||
|
|
||||||
// for original
|
// for original
|
||||||
const key = `${config.drive.prefix}/${uuid.v4()}${ext}`;
|
const key = `${meta.objectStoragePrefix}/${uuid.v4()}${ext}`;
|
||||||
const url = `${ baseUrl }/${ key }`;
|
const url = `${ baseUrl }/${ key }`;
|
||||||
|
|
||||||
// for alts
|
// for alts
|
||||||
|
@ -68,7 +69,7 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
|
||||||
];
|
];
|
||||||
|
|
||||||
if (alts.webpublic) {
|
if (alts.webpublic) {
|
||||||
webpublicKey = `${config.drive.prefix}/${uuid.v4()}.${alts.webpublic.ext}`;
|
webpublicKey = `${meta.objectStoragePrefix}/${uuid.v4()}.${alts.webpublic.ext}`;
|
||||||
webpublicUrl = `${ baseUrl }/${ webpublicKey }`;
|
webpublicUrl = `${ baseUrl }/${ webpublicKey }`;
|
||||||
|
|
||||||
logger.info(`uploading webpublic: ${webpublicKey}`);
|
logger.info(`uploading webpublic: ${webpublicKey}`);
|
||||||
|
@ -76,7 +77,7 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alts.thumbnail) {
|
if (alts.thumbnail) {
|
||||||
thumbnailKey = `${config.drive.prefix}/${uuid.v4()}.${alts.thumbnail.ext}`;
|
thumbnailKey = `${meta.objectStoragePrefix}/${uuid.v4()}.${alts.thumbnail.ext}`;
|
||||||
thumbnailUrl = `${ baseUrl }/${ thumbnailKey }`;
|
thumbnailUrl = `${ baseUrl }/${ thumbnailKey }`;
|
||||||
|
|
||||||
logger.info(`uploading thumbnail: ${thumbnailKey}`);
|
logger.info(`uploading thumbnail: ${thumbnailKey}`);
|
||||||
|
@ -194,7 +195,15 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
|
||||||
* Upload to ObjectStorage
|
* Upload to ObjectStorage
|
||||||
*/
|
*/
|
||||||
async function upload(key: string, stream: fs.ReadStream | Buffer, type: string, filename?: string) {
|
async function upload(key: string, stream: fs.ReadStream | Buffer, type: string, filename?: string) {
|
||||||
const minio = new Minio.Client(config.drive!.config);
|
const meta = await fetchMeta();
|
||||||
|
|
||||||
|
const minio = new Minio.Client({
|
||||||
|
endPoint: meta.objectStorageEndpoint!,
|
||||||
|
port: meta.objectStoragePort ? meta.objectStoragePort : undefined,
|
||||||
|
useSSL: meta.objectStorageUseSSL,
|
||||||
|
accessKey: meta.objectStorageAccessKey!,
|
||||||
|
secretKey: meta.objectStorageSecretKey!,
|
||||||
|
});
|
||||||
|
|
||||||
const metadata = {
|
const metadata = {
|
||||||
'Content-Type': type,
|
'Content-Type': type,
|
||||||
|
@ -203,7 +212,7 @@ async function upload(key: string, stream: fs.ReadStream | Buffer, type: string,
|
||||||
|
|
||||||
if (filename) metadata['Content-Disposition'] = contentDisposition('inline', filename);
|
if (filename) metadata['Content-Disposition'] = contentDisposition('inline', filename);
|
||||||
|
|
||||||
await minio.putObject(config.drive!.bucket!, key, stream, undefined, metadata);
|
await minio.putObject(meta.objectStorageBucket!, key, stream, undefined, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteOldFile(user: IRemoteUser) {
|
async function deleteOldFile(user: IRemoteUser) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as Minio from 'minio';
|
import * as Minio from 'minio';
|
||||||
import config from '../../config';
|
|
||||||
import { DriveFile } from '../../models/entities/drive-file';
|
import { DriveFile } from '../../models/entities/drive-file';
|
||||||
import { InternalStorage } from './internal-storage';
|
import { InternalStorage } from './internal-storage';
|
||||||
import { DriveFiles, Instances, Notes } from '../../models';
|
import { DriveFiles, Instances, Notes } from '../../models';
|
||||||
import { driveChart, perUserDriveChart, instanceChart } from '../chart';
|
import { driveChart, perUserDriveChart, instanceChart } from '../chart';
|
||||||
|
import { fetchMeta } from '../../misc/fetch-meta';
|
||||||
|
|
||||||
export default async function(file: DriveFile, isExpired = false) {
|
export default async function(file: DriveFile, isExpired = false) {
|
||||||
if (file.storedInternal) {
|
if (file.storedInternal) {
|
||||||
|
@ -17,16 +17,24 @@ export default async function(file: DriveFile, isExpired = false) {
|
||||||
InternalStorage.del(file.webpublicAccessKey!);
|
InternalStorage.del(file.webpublicAccessKey!);
|
||||||
}
|
}
|
||||||
} else if (!file.isLink) {
|
} else if (!file.isLink) {
|
||||||
const minio = new Minio.Client(config.drive!.config);
|
const meta = await fetchMeta();
|
||||||
|
|
||||||
await minio.removeObject(config.drive!.bucket!, file.accessKey!);
|
const minio = new Minio.Client({
|
||||||
|
endPoint: meta.objectStorageEndpoint!,
|
||||||
|
port: meta.objectStoragePort ? meta.objectStoragePort : undefined,
|
||||||
|
useSSL: meta.objectStorageUseSSL,
|
||||||
|
accessKey: meta.objectStorageAccessKey!,
|
||||||
|
secretKey: meta.objectStorageSecretKey!,
|
||||||
|
});
|
||||||
|
|
||||||
|
await minio.removeObject(meta.objectStorageBucket!, file.accessKey!);
|
||||||
|
|
||||||
if (file.thumbnailUrl) {
|
if (file.thumbnailUrl) {
|
||||||
await minio.removeObject(config.drive!.bucket!, file.thumbnailAccessKey!);
|
await minio.removeObject(meta.objectStorageBucket!, file.thumbnailAccessKey!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.webpublicUrl) {
|
if (file.webpublicUrl) {
|
||||||
await minio.removeObject(config.drive!.bucket!, file.webpublicAccessKey!);
|
await minio.removeObject(meta.objectStorageBucket!, file.webpublicAccessKey!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue