Skip to content

Commit

Permalink
v12.23Q4.4 🎉
Browse files Browse the repository at this point in the history
v12.23Q4.4
  • Loading branch information
nexryai authored Dec 25, 2023
2 parents 36a110e + 2b0f04a commit a8e75c0
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-image-devel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ jobs:
- uses: docker/build-push-action@v2
with:
context: .
#platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64
push: true
tags: nexryai/nexkey:devel
2 changes: 1 addition & 1 deletion .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ jobs:
- uses: docker/build-push-action@v2
with:
context: .
#platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64
push: true
tags: nexryai/nexkey:latest
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 12.23Q4.4
- Backend: deep-email-validatorをdevmehq/email-validator-jsで置き換えより高精度で捨てアド判定ができるように
- Feat: arm64のDockerコンテナを利用可能に
- Fix: 画像のクロップが永遠に終わらない問題を修正
- Fix (Client): ActiveEmailValidationの設定がコントロールパネルに表示されない問題を修正

### 既知の問題
- page等でAiScriptが動作しない問題 (#531) がありますが、原因が分からずこのバージョンでの修正は実現しませんでした。

## 12.23Q4.3
- 依存関係の更新
- gulpやめる
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nexkey",
"version": "12.23Q4.3",
"version": "12.23Q4.4",
"codename": "chirigiku",
"repository": {
"type": "git",
Expand Down
5 changes: 3 additions & 2 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
"chokidar": "^3.3.1",
"lodash": "^4.17.21"
},
"overrides": { "multer": { "busboy": "1.6.0" } },
"dependencies": {
"@bull-board/koa": "5.9.1",
"@devmehq/email-validator-js": "1.0.19",
"@discordapp/twemoji": "15.0.2",
"@elastic/elasticsearch": "8.10.0",
"@koa/cors": "5.0.0",
Expand Down Expand Up @@ -44,7 +46,6 @@
"color-convert": "2.0.1",
"content-disposition": "0.5.4",
"date-fns": "2.30.0",
"deep-email-validator": "0.1.21",
"escape-regexp": "0.0.1",
"extract-domain": "4.1.3",
"feed": "4.2.2",
Expand Down Expand Up @@ -80,10 +81,10 @@
"node-fetch": "3.3.2",
"nodemailer": "6.9.7",
"os-utils": "0.0.14",
"otpauth": "9.1.5",
"parse5": "7.1.2",
"pg": "8.11.3",
"private-ip": "3.0.1",
"otpauth": "9.1.5",
"probe-image-size": "7.2.3",
"promise-limit": "2.7.0",
"pug": "3.0.2",
Expand Down
86 changes: 75 additions & 11 deletions packages/backend/src/server/proxy/proxy-media.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,88 @@
import * as fs from "node:fs";
import * as querystring from "querystring";
import Koa from "koa";
import config from "@/config/index.js";
import { IImage, convertToWebp } from "@/services/drive/image-processor.js";
import { createTemp } from "@/misc/create-temp.js";
import { downloadUrl } from "@/misc/download-url.js";
import { detectType } from "@/misc/get-file-info.js";
import { StatusError } from "@/misc/fetch.js";
import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
import { isMimeImage } from "@/misc/is-mime-image.js";
import { serverLogger } from "../index.js";

// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export async function proxyMedia(ctx: Koa.Context) {
let redirectUrl: string;

// 本家仕様にするの面倒なのでとりあえず未設定でもどっかのプロキシに投げる
if (config.mediaProxy == null) {
redirectUrl = "https://proxy.sda1.net/";
if (config.mediaProxy == null || ctx.query.mustOrigin === "1") {
// MediaProxyを使わない場合
const url = "url" in ctx.query ? ctx.query.url : "https://" + ctx.params.url;

if (typeof url !== "string") {
ctx.status = 400;
return;
}

// Create temp file
const [path, cleanup] = await createTemp();

try {
await downloadUrl(url, path);

const { mime, ext } = await detectType(path);
const isConvertibleImage = isMimeImage(mime, "sharp-convertible-image");

let image: IImage;

if ("static" in ctx.query && isConvertibleImage) {
image = await convertToWebp(path, 498, 280);
} else if ("preview" in ctx.query && isConvertibleImage) {
image = await convertToWebp(path, 200, 200);
} else if ("avatar" in ctx.query && isConvertibleImage) {
image = await convertToWebp(path, 320, 320);
} else if ("ticker" in ctx.query && isConvertibleImage) {
image = await convertToWebp(path, 64, 64);
} else if ("thumbnail" in ctx.query && isConvertibleImage) {
image = await convertToWebp(path, 500, 400);
} else if ("badge" in ctx.query && isConvertibleImage) {
image = await convertToWebp(path, 96, 96);
} else if (mime === "image/svg+xml") {
image = await convertToWebp(path, 2048, 2048, 1);
} else if (!mime.startsWith("image/") || !FILE_TYPE_BROWSERSAFE.includes(mime)) {
throw new StatusError("Rejected type", 403, "Rejected type");
} else {
image = {
data: fs.readFileSync(path),
ext,
type: mime,
};
}

ctx.set("Content-Type", image.type);
ctx.set("Cache-Control", "max-age=31536000, immutable");
ctx.body = image.data;
} catch (e) {
serverLogger.error(`${e}`);

if (e instanceof StatusError && (e.statusCode === 302 || e.isClientError)) {
ctx.status = e.statusCode;
} else {
ctx.status = 500;
}
} finally {
cleanup();
}
} else {
// 外部のMediaProxyを使うはずなのにこっちに誘導されたならリダイレクト
redirectUrl = config.mediaProxy;
}
// パスとパラメータを取得
const { path, query } = ctx.request;
const queryString = querystring.stringify(query);

// パスとパラメータを取得
const { path, query } = ctx.request;
const queryString = querystring.stringify(query);
// パスとパラメータを維持してリダイレクト
const targetUrl = redirectUrl + path + (queryString ? `?${queryString}` : "");

// パスとパラメータを維持してリダイレクト
const targetUrl = redirectUrl + path + (queryString ? `?${queryString}` : "");

ctx.redirect(targetUrl);
ctx.redirect(targetUrl);
}
}
35 changes: 22 additions & 13 deletions packages/backend/src/services/validate-email-for-account.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { validate as validateEmail } from "deep-email-validator";
import { verifyEmail, isDisposableEmail } from "@devmehq/email-validator-js";
import extractDomain from "extract-domain";
import { UserProfiles } from "@/models/index.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
Expand All @@ -14,23 +14,32 @@ export async function validateEmailForAccount(emailAddress: string): Promise<{
email: emailAddress,
});

const validated = meta.enableActiveEmailValidation ? await validateEmail({
email: emailAddress,
validateRegex: true,
validateMx: true,
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
validateDisposable: true, // 捨てアドかどうかチェック
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
}) : { valid: true };
let validated;

const { validFormat, validMx } = await verifyEmail({ emailAddress: emailAddress, verifyMx: true, verifySmtp: false, timeout: 3000 });

if (!validFormat) {
validated = { valid: false, reason: "regex" };
} else if (meta.enableActiveEmailValidation) {
if (!validMx) {
validated = { valid: false, reason: "mx" };
} else if (isDisposableEmail(emailAddress)) {
validated = { valid: false, reason: "disposable" };
} else {
validated = { valid: true };
}
} else {
validated = { valid: true };
}

// メールドメインブロックを判定
const domain = extractDomain(emailAddress).toLowerCase();
let blockedemaildomain = false;
let blockedEmailDomain = false;
if (meta.blockedEmailDomains.some(x => domain.endsWith(x))) {
blockedemaildomain = true;
blockedEmailDomain = true;
}

const available = exist === 0 && validated.valid && !blockedemaildomain;
const available = exist === 0 && validated.valid && !blockedEmailDomain;

return {
available,
Expand All @@ -40,7 +49,7 @@ export async function validateEmailForAccount(emailAddress: string): Promise<{
validated.reason === "disposable" ? "disposable" :
validated.reason === "mx" ? "mx" :
validated.reason === "smtp" ? "smtp" :
blockedemaildomain ? "blocked" :
blockedEmailDomain ? "blocked" :
null,
};
}
52 changes: 14 additions & 38 deletions packages/backend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"

"@devmehq/email-validator-js@1.0.19":
version "1.0.19"
resolved "https://registry.yarnpkg.com/@devmehq/email-validator-js/-/email-validator-js-1.0.19.tgz#e025b6d6520436063f98f79384ad00dcb998c4c2"
integrity sha512-Z2qlnD2xddvXz+5e26czIvPJysUfvVi+9mjyNG/XH7eZbqF93hoU/Ff4KfGv9UoPmj7uhRW1k+i9JFtae7sc3w==
dependencies:
"@types/psl" "1.1.3"
psl "1.9.0"

"@digitalbazaar/http-client@^3.4.1":
version "3.4.1"
resolved "https://registry.yarnpkg.com/@digitalbazaar/http-client/-/http-client-3.4.1.tgz#5116fc44290d647cfe4b615d1f3fad9d6005e44d"
Expand Down Expand Up @@ -814,11 +822,6 @@
"@types/keygrip" "*"
"@types/node" "*"

"@types/disposable-email-domains@^1.0.1":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/disposable-email-domains/-/disposable-email-domains-1.0.4.tgz#2d28452e2d3a97069217c7398932aa0cb4f32b62"
integrity sha512-AmKPD8vBZzvey/jeg+YAIH/xJE3D6edOXz+YUooSCcHesGzFyzke83kj1j4d0LUR9nkSHIRklUVdcAMleuWLpg==

"@types/escape-regexp@0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.3.tgz#670ae8d6a38ba2530d5b55238ff70aba1596d20a"
Expand Down Expand Up @@ -1044,6 +1047,11 @@
dependencies:
"@types/node" "*"

"@types/psl@1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@types/psl/-/psl-1.1.3.tgz#c1e9febd70e7df248ac9911cdd145454643aa28f"
integrity sha512-Iu174JHfLd7i/XkXY6VDrqSlPvTDQOtQI7wNAXKKOAADJ9TduRLkNdMgjGiMxSttUIZnomv81JAbAbC0DhggxA==

"@types/pug@2.0.8":
version "2.0.8"
resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.8.tgz#1a85ecb760f7472d9ec3bab19bfe17454c69499d"
Expand Down Expand Up @@ -1627,13 +1635,6 @@ aws-sdk@2.1483.0:
uuid "8.0.0"
xml2js "0.5.0"

axios@^0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
dependencies:
follow-redirects "^1.14.4"

b4a@^1.6.4:
version "1.6.4"
resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9"
Expand Down Expand Up @@ -2357,16 +2358,6 @@ decompress-response@^6.0.0:
dependencies:
mimic-response "^3.1.0"

deep-email-validator@0.1.21:
version "0.1.21"
resolved "https://registry.yarnpkg.com/deep-email-validator/-/deep-email-validator-0.1.21.tgz#5d0120fe1aeae83ab7cb39378a40a381b681219f"
integrity sha512-DBAmMzbr+MAubXQ+TS9tZuPwLcdKscb8YzKZiwoLqF3NmaeEgXvSSHhZ0EXOFeKFE2FNWC4mNXCyiQ/JdFXUwg==
dependencies:
"@types/disposable-email-domains" "^1.0.1"
axios "^0.24.0"
disposable-email-domains "^1.0.59"
mailcheck "^1.1.1"

deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
Expand Down Expand Up @@ -2474,11 +2465,6 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"

disposable-email-domains@^1.0.59:
version "1.0.62"
resolved "https://registry.yarnpkg.com/disposable-email-domains/-/disposable-email-domains-1.0.62.tgz#bb66d3c387397dd8938aaf63a90505984f729265"
integrity sha512-LBQvhRw7mznQTPoyZbsmYeNOZt1pN5aCsx4BAU/3siVFuiM9f2oyKzUaB8v1jbxFjE3aYqYiMo63kAL4pHgfWQ==

doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
Expand Down Expand Up @@ -3119,11 +3105,6 @@ fluent-ffmpeg@2.1.2:
async ">=0.2.9"
which "^1.1.1"

follow-redirects@^1.14.4:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==

for-each@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
Expand Down Expand Up @@ -4509,11 +4490,6 @@ luxon@^3.2.1:
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48"
integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==

mailcheck@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34"
integrity sha512-3WjL8+ZDouZwKlyJBMp/4LeziLFXgleOdsYu87piGcMLqhBzCsy2QFdbtAwv757TFC/rtqd738fgJw1tFQCSgA==

make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
Expand Down Expand Up @@ -5500,7 +5476,7 @@ proto-list@~1.2.1:
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==

psl@^1.1.33, psl@^1.9.0:
psl@1.9.0, psl@^1.1.33, psl@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/components/MkCropperDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const props = defineProps<{
aspectRatio: number;
}>();
const imgUrl = getProxiedImageUrl(props.file.url);
const imgUrl = getProxiedImageUrl(props.file.url, "thumbnail", true);
let dialogEl = $ref<InstanceType<typeof XModalWindow>>();
let imgEl = $ref<HTMLImageElement>();
let cropper: Cropper | null = null;
Expand Down
17 changes: 14 additions & 3 deletions packages/client/src/pages/admin/security.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,26 @@
<XBotProtection/>
</FormFolder>

<FormFolder class="_formBlock">
<template #label>Active Email Validation</template>
<template v-if="enableActiveEmailValidation" #suffix>Enabled</template>
<template v-else #suffix>Disabled</template>

<div class="_formRoot">
<span class="_formBlock">{{ i18n.ts.activeEmailValidationDescription }}</span>
<FormSwitch v-model="enableActiveEmailValidation" class="_formBlock" @update:model-value="save">
<template #label>Enable</template>
</FormSwitch>
</div>
</FormFolder>

<FormFolder class="_formBlock">
<template #label>Log IP address</template>
<template v-if="enableIpLogging" #suffix>Enabled</template>
<template v-else #suffix>Disabled</template>

<div class="_formRoot">
<FormSwitch v-model="enableIpLogging" class="_formBlock" @update:modelValue="save">
<FormSwitch v-model="enableIpLogging" class="_formBlock" @update:model-value="save">
<template #label>Enable</template>
</FormSwitch>
</div>
Expand Down Expand Up @@ -54,9 +67,7 @@ import XBotProtection from "./bot-protection.vue";
import XHeader from "./_header_.vue";
import FormFolder from "@/components/form/folder.vue";
import FormSwitch from "@/components/form/switch.vue";
import FormInfo from "@/components/MkInfo.vue";
import FormSuspense from "@/components/form/suspense.vue";
import FormSection from "@/components/form/section.vue";
import FormInput from "@/components/form/input.vue";
import FormButton from "@/components/MkButton.vue";
import * as os from "@/os";
Expand Down
Loading

0 comments on commit a8e75c0

Please sign in to comment.