mirror of
https://github.com/misskey-dev/misskey.git
synced 2025-04-10 14:56:39 +09:00
Merge branch 'develop' into pr/13929
This commit is contained in:
commit
dec4a40bfd
@ -6,9 +6,10 @@
|
|||||||
### Client
|
### Client
|
||||||
- Feat: ノート単体・ユーザーのノート・クリップのノートの埋め込み機能
|
- Feat: ノート単体・ユーザーのノート・クリップのノートの埋め込み機能
|
||||||
- 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です
|
- 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です
|
||||||
|
- サイズ制限を超過するファイルをアップロードしようとした際にエラーを出すように
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
-
|
- ファイルがサイズの制限を超えてアップロードされた際にエラーを返さなかった問題を修正
|
||||||
|
|
||||||
|
|
||||||
## 2024.8.0
|
## 2024.8.0
|
||||||
|
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
@ -5080,6 +5080,10 @@ export interface Locale extends ILocale {
|
|||||||
* このユーザーのノート一覧
|
* このユーザーのノート一覧
|
||||||
*/
|
*/
|
||||||
"noteOfThisUser": string;
|
"noteOfThisUser": string;
|
||||||
|
/**
|
||||||
|
* これ以上このクリップにノートを追加できません。
|
||||||
|
*/
|
||||||
|
"clipNoteLimitExceeded": string;
|
||||||
"_delivery": {
|
"_delivery": {
|
||||||
/**
|
/**
|
||||||
* 配信状態
|
* 配信状態
|
||||||
|
@ -1266,6 +1266,7 @@ createdAntennas: "作成したアンテナ"
|
|||||||
fromX: "{x}から"
|
fromX: "{x}から"
|
||||||
copyEmbedCode: "埋め込みコードをコピー"
|
copyEmbedCode: "埋め込みコードをコピー"
|
||||||
noteOfThisUser: "このユーザーのノート一覧"
|
noteOfThisUser: "このユーザーのノート一覧"
|
||||||
|
clipNoteLimitExceeded: "これ以上このクリップにノートを追加できません。"
|
||||||
|
|
||||||
_delivery:
|
_delivery:
|
||||||
status: "配信状態"
|
status: "配信状態"
|
||||||
|
@ -133,7 +133,7 @@ export type Config = {
|
|||||||
proxySmtp: string | undefined;
|
proxySmtp: string | undefined;
|
||||||
proxyBypassHosts: string[] | undefined;
|
proxyBypassHosts: string[] | undefined;
|
||||||
allowedPrivateNetworks: string[] | undefined;
|
allowedPrivateNetworks: string[] | undefined;
|
||||||
maxFileSize: number | undefined;
|
maxFileSize: number;
|
||||||
clusterLimit: number | undefined;
|
clusterLimit: number | undefined;
|
||||||
id: string;
|
id: string;
|
||||||
outgoingAddress: string | undefined;
|
outgoingAddress: string | undefined;
|
||||||
@ -258,7 +258,7 @@ export function loadConfig(): Config {
|
|||||||
proxySmtp: config.proxySmtp,
|
proxySmtp: config.proxySmtp,
|
||||||
proxyBypassHosts: config.proxyBypassHosts,
|
proxyBypassHosts: config.proxyBypassHosts,
|
||||||
allowedPrivateNetworks: config.allowedPrivateNetworks,
|
allowedPrivateNetworks: config.allowedPrivateNetworks,
|
||||||
maxFileSize: config.maxFileSize,
|
maxFileSize: config.maxFileSize ?? 262144000,
|
||||||
clusterLimit: config.clusterLimit,
|
clusterLimit: config.clusterLimit,
|
||||||
outgoingAddress: config.outgoingAddress,
|
outgoingAddress: config.outgoingAddress,
|
||||||
outgoingAddressFamily: config.outgoingAddressFamily,
|
outgoingAddressFamily: config.outgoingAddressFamily,
|
||||||
|
@ -42,7 +42,7 @@ export class DownloadService {
|
|||||||
|
|
||||||
const timeout = 30 * 1000;
|
const timeout = 30 * 1000;
|
||||||
const operationTimeout = 60 * 1000;
|
const operationTimeout = 60 * 1000;
|
||||||
const maxSize = this.config.maxFileSize ?? 262144000;
|
const maxSize = this.config.maxFileSize;
|
||||||
|
|
||||||
const urlObj = new URL(url);
|
const urlObj = new URL(url);
|
||||||
let filename = urlObj.pathname.split('/').pop() ?? 'untitled';
|
let filename = urlObj.pathname.split('/').pop() ?? 'untitled';
|
||||||
|
@ -129,6 +129,7 @@ export class MetaEntityService {
|
|||||||
mediaProxy: this.config.mediaProxy,
|
mediaProxy: this.config.mediaProxy,
|
||||||
enableUrlPreview: instance.urlPreviewEnabled,
|
enableUrlPreview: instance.urlPreviewEnabled,
|
||||||
noteSearchableScope: (this.config.meilisearch == null || this.config.meilisearch.scope !== 'local') ? 'global' : 'local',
|
noteSearchableScope: (this.config.meilisearch == null || this.config.meilisearch.scope !== 'local') ? 'global' : 'local',
|
||||||
|
maxFileSize: this.config.maxFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
return packed;
|
return packed;
|
||||||
|
@ -253,6 +253,10 @@ export const packedMetaLiteSchema = {
|
|||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
default: 'local',
|
default: 'local',
|
||||||
},
|
},
|
||||||
|
maxFileSize: {
|
||||||
|
type: 'number',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@ -199,9 +199,18 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [path] = await createTemp();
|
const [path, cleanup] = await createTemp();
|
||||||
await stream.pipeline(multipartData.file, fs.createWriteStream(path));
|
await stream.pipeline(multipartData.file, fs.createWriteStream(path));
|
||||||
|
|
||||||
|
// ファイルサイズが制限を超えていた場合
|
||||||
|
// なお truncated はストリームを読み切ってからでないと機能しないため、stream.pipeline より後にある必要がある
|
||||||
|
if (multipartData.file.truncated) {
|
||||||
|
cleanup();
|
||||||
|
reply.code(413);
|
||||||
|
reply.send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fields = {} as Record<string, unknown>;
|
const fields = {} as Record<string, unknown>;
|
||||||
for (const [k, v] of Object.entries(multipartData.fields)) {
|
for (const [k, v] of Object.entries(multipartData.fields)) {
|
||||||
fields[k] = typeof v === 'object' && 'value' in v ? v.value : undefined;
|
fields[k] = typeof v === 'object' && 'value' in v ? v.value : undefined;
|
||||||
|
@ -49,7 +49,7 @@ export class ApiServerService {
|
|||||||
|
|
||||||
fastify.register(multipart, {
|
fastify.register(multipart, {
|
||||||
limits: {
|
limits: {
|
||||||
fileSize: this.config.maxFileSize ?? 262144000,
|
fileSize: this.config.maxFileSize,
|
||||||
files: 1,
|
files: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -155,7 +155,7 @@
|
|||||||
|
|
||||||
if (!errorsElement) {
|
if (!errorsElement) {
|
||||||
document.body.innerHTML = `
|
document.body.innerHTML = `
|
||||||
<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-alert-triangle" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
<path d="M12 9v2m0 4v.01"></path>
|
<path d="M12 9v2m0 4v.01"></path>
|
||||||
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
|
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
|
||||||
@ -167,7 +167,7 @@
|
|||||||
<p><b>The following actions may solve the problem. / 以下を行うと解決する可能性があります。</b></p>
|
<p><b>The following actions may solve the problem. / 以下を行うと解決する可能性があります。</b></p>
|
||||||
<p>Update your os and browser / ブラウザおよびOSを最新バージョンに更新する</p>
|
<p>Update your os and browser / ブラウザおよびOSを最新バージョンに更新する</p>
|
||||||
<p>Disable an adblocker / アドブロッカーを無効にする</p>
|
<p>Disable an adblocker / アドブロッカーを無効にする</p>
|
||||||
<p>Clear the browser cache / ブラウザのキャッシュをクリアする</p>
|
<p>Clear the browser cache / ブラウザのキャッシュをクリアする</p>
|
||||||
<p>(Tor Browser) Set dom.webaudio.enabled to true / dom.webaudio.enabledをtrueに設定する</p>
|
<p>(Tor Browser) Set dom.webaudio.enabled to true / dom.webaudio.enabledをtrueに設定する</p>
|
||||||
<details style="color: #86b300;">
|
<details style="color: #86b300;">
|
||||||
<summary>Other options / その他のオプション</summary>
|
<summary>Other options / その他のオプション</summary>
|
||||||
|
@ -36,8 +36,6 @@ html
|
|||||||
link(rel='prefetch' href=serverErrorImageUrl)
|
link(rel='prefetch' href=serverErrorImageUrl)
|
||||||
link(rel='prefetch' href=infoImageUrl)
|
link(rel='prefetch' href=infoImageUrl)
|
||||||
link(rel='prefetch' href=notFoundImageUrl)
|
link(rel='prefetch' href=notFoundImageUrl)
|
||||||
//- https://github.com/misskey-dev/misskey/issues/9842
|
|
||||||
link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v3.3.0')
|
|
||||||
link(rel='modulepreload' href=`/vite/${entry.file}`)
|
link(rel='modulepreload' href=`/vite/${entry.file}`)
|
||||||
|
|
||||||
if !config.frontendManifestExists
|
if !config.frontendManifestExists
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
// https://vitejs.dev/config/build-options.html#build-modulepreload
|
// https://vitejs.dev/config/build-options.html#build-modulepreload
|
||||||
import 'vite/modulepreload-polyfill';
|
import 'vite/modulepreload-polyfill';
|
||||||
|
|
||||||
|
import '@tabler/icons-webfont/dist/tabler-icons.scss';
|
||||||
|
|
||||||
import '@/style.scss';
|
import '@/style.scss';
|
||||||
import { mainBoot } from '@/boot/main-boot.js';
|
import { mainBoot } from '@/boot/main-boot.js';
|
||||||
import { subBoot } from '@/boot/sub-boot.js';
|
import { subBoot } from '@/boot/sub-boot.js';
|
||||||
|
@ -3,11 +3,6 @@
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// devモードで起動される際(index.htmlを使うとき)はrouterが暴発してしまってうまく読み込めない。
|
|
||||||
// よって、devモードとして起動されるときはビルド時に組み込む形としておく。
|
|
||||||
// (pnpm start時はpugファイルの中で静的リソースとして読み込むようになっており、この問題は起こっていない)
|
|
||||||
import '@tabler/icons-webfont/dist/tabler-icons.scss';
|
|
||||||
|
|
||||||
await main();
|
await main();
|
||||||
|
|
||||||
import('@/_boot_.js');
|
import('@/_boot_.js');
|
||||||
|
@ -245,7 +245,7 @@ const submitText = computed((): string => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const textLength = computed((): number => {
|
const textLength = computed((): number => {
|
||||||
return (text.value + imeText.value).trim().length;
|
return (text.value + imeText.value).length;
|
||||||
});
|
});
|
||||||
|
|
||||||
const maxTextLength = computed((): number => {
|
const maxTextLength = computed((): number => {
|
||||||
|
@ -67,6 +67,11 @@ export async function getNoteClipMenu(props: {
|
|||||||
});
|
});
|
||||||
if (props.currentClip?.id === clip.id) props.isDeleted.value = true;
|
if (props.currentClip?.id === clip.id) props.isDeleted.value = true;
|
||||||
}
|
}
|
||||||
|
} else if (err.id === 'f0dba960-ff73-4615-8df4-d6ac5d9dc118') {
|
||||||
|
os.alert({
|
||||||
|
type: 'error',
|
||||||
|
text: i18n.ts.clipNoteLimitExceeded,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
|
@ -13,6 +13,7 @@ import { apiUrl } from '@/config.js';
|
|||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { alert } from '@/os.js';
|
import { alert } from '@/os.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
import { instance } from '@/instance.js';
|
||||||
|
|
||||||
type Uploading = {
|
type Uploading = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -39,6 +40,15 @@ export function uploadFile(
|
|||||||
|
|
||||||
if (folder && typeof folder === 'object') folder = folder.id;
|
if (folder && typeof folder === 'object') folder = folder.id;
|
||||||
|
|
||||||
|
if (file.size > instance.maxFileSize) {
|
||||||
|
alert({
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.ts.failedToUpload,
|
||||||
|
text: i18n.ts.cannotUploadBecauseExceedsFileSizeLimit,
|
||||||
|
});
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const id = uuid();
|
const id = uuid();
|
||||||
|
|
||||||
|
@ -4947,6 +4947,7 @@ export type components = {
|
|||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
noteSearchableScope: 'local' | 'global';
|
noteSearchableScope: 'local' | 'global';
|
||||||
|
maxFileSize: number;
|
||||||
};
|
};
|
||||||
MetaDetailedOnly: {
|
MetaDetailedOnly: {
|
||||||
features?: {
|
features?: {
|
||||||
|
Loading…
Reference in New Issue
Block a user