Compare commits
No commits in common. "7c93e1a91aafbd359b84e8896f0101fac473d4cf" and "7c309e371d8fe24d97602d2556d6217efb3549a6" have entirely different histories.
7c93e1a91a
...
7c309e371d
18 changed files with 47 additions and 94 deletions
|
@ -2031,22 +2031,3 @@ _iconSets:
|
||||||
light: 細線
|
light: 細線
|
||||||
showAttachedNotes: 顯示有此附件的貼文
|
showAttachedNotes: 顯示有此附件的貼文
|
||||||
attachedToNotes: 帶有此附件的貼文
|
attachedToNotes: 帶有此附件的貼文
|
||||||
enablePullToRefresh: "啟用「向下拉以重新整理」"
|
|
||||||
enableTimelineStreaming: "自動更新時間軸"
|
|
||||||
noLanguage: "無語言"
|
|
||||||
publishTimelines: "允許未登入的使用者查看時間軸"
|
|
||||||
publishTimelinesDescription: "啟用後,未登入的使用者可於 {url} 查看本地時間軸及公開時間軸"
|
|
||||||
pullDownToReload: "向下拉以重新整理"
|
|
||||||
pullToRefreshThreshold: "觸發重新整理需向下拉的距離"
|
|
||||||
releaseToReload: "放開以重新整理"
|
|
||||||
reloading: "重新整理中"
|
|
||||||
replyMute: "靜音回覆貼文"
|
|
||||||
replyUnmute: "解除靜音回覆貼文"
|
|
||||||
searchPostsWithFiles: "僅帶有附件的貼文"
|
|
||||||
searchRange: "日期範圍 (選填)"
|
|
||||||
searchRangeDescription: "如欲搜尋特定期間的貼文,請以「20220615-20231031」的格式輸入日期範圍。今年的日期可省略年份(例如0105-0106、20231105-0110)。\n\n開始日期和結果日期可擇一省略。舉例來說,「-0102」表示僅搜尋今年1月2日為止的貼文,「20231026-」表示僅搜尋2023年10月26日以後的貼文。"
|
|
||||||
searchUsers: "發文者 (選填)"
|
|
||||||
searchUsersDescription: "如欲搜尋特定使用者的貼文,請以「@user@example.com(本地使用者則為 @user)」的格式輸入發文者的ID。輸入網域名稱(example.com)以搜尋特定伺服器的貼文。\n\n輸入「me」以搜尋自己的所有貼文,包含不在主頁顯示、追隨者、指定使用者、祕密貼文。\n\n輸入「local」以搜尋本地伺服器的貼文。"
|
|
||||||
searchWords: "搜尋關鍵字 / 查詢ID或URL"
|
|
||||||
searchWordsDescription: "如欲搜尋貼文,請在此欄位輸入欲搜尋的關鍵字。以空格分隔關鍵字以進行AND搜尋、在關鍵字之間插入「OR」以進行OR搜尋。\n舉例來說,輸入「早上 晚上」會搜尋包含「早上」和「晚上」的貼文,「早上 OR 晚上」會搜尋包含「早上」或「晚上」(或兩者皆包含)的貼文。\n\n如欲前往特定使用者或貼文的頁面,請在此欄位輸入使用者ID(@user@example.com)或貼文的URL,並點擊「查詢」按鈕。點擊「搜尋」按鈕則會搜尋字面上包含輸入的ID或URL的貼文。"
|
|
||||||
suggested: "建議"
|
|
||||||
|
|
|
@ -266,8 +266,6 @@ if (!nativeBinding) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
stringToAcct,
|
|
||||||
acctToString,
|
|
||||||
nativeRandomStr,
|
nativeRandomStr,
|
||||||
IdConvertType,
|
IdConvertType,
|
||||||
convertId,
|
convertId,
|
||||||
|
@ -276,8 +274,6 @@ const {
|
||||||
nativeInitIdGenerator,
|
nativeInitIdGenerator,
|
||||||
} = nativeBinding;
|
} = nativeBinding;
|
||||||
|
|
||||||
module.exports.stringToAcct = stringToAcct;
|
|
||||||
module.exports.acctToString = acctToString;
|
|
||||||
module.exports.nativeRandomStr = nativeRandomStr;
|
module.exports.nativeRandomStr = nativeRandomStr;
|
||||||
module.exports.IdConvertType = IdConvertType;
|
module.exports.IdConvertType = IdConvertType;
|
||||||
module.exports.convertId = convertId;
|
module.exports.convertId = convertId;
|
||||||
|
|
|
@ -32,7 +32,7 @@ tokio = { version = "1.35.1", features = ["full"] }
|
||||||
utoipa = "4.1.0"
|
utoipa = "4.1.0"
|
||||||
|
|
||||||
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
|
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
|
||||||
napi = { version = "2.14.1", default-features = false, features = ["napi9", "tokio_rt"], optional = true }
|
napi = { version = "2.14.1", default-features = false, features = ["napi6", "tokio_rt"], optional = true }
|
||||||
napi-derive = { version = "2.14.5", optional = true }
|
napi-derive = { version = "2.14.5", optional = true }
|
||||||
basen = "0.1.0"
|
basen = "0.1.0"
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
use napi_derive::napi;
|
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
|
||||||
#[napi(object)]
|
|
||||||
pub struct Acct {
|
|
||||||
pub username: String,
|
|
||||||
pub host: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn string_to_acct(acct: String) -> Acct {
|
|
||||||
let split: Vec<&str> = if let Some(stripped) = acct.strip_prefix('@') {
|
|
||||||
stripped
|
|
||||||
} else {
|
|
||||||
&acct
|
|
||||||
}
|
|
||||||
.split('@')
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Acct {
|
|
||||||
username: split[0].to_string(),
|
|
||||||
host: if split.len() == 1 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(split[1].to_string())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn acct_to_string(acct: Acct) -> String {
|
|
||||||
match acct.host {
|
|
||||||
Some(host) => format!("{}@{}", acct.username, host),
|
|
||||||
None => acct.username,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod acct;
|
|
||||||
pub mod id;
|
pub mod id;
|
||||||
pub mod random;
|
pub mod random;
|
||||||
|
|
14
packages/backend/src/misc/acct.ts
Normal file
14
packages/backend/src/misc/acct.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
export type Acct = {
|
||||||
|
username: string;
|
||||||
|
host: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function parse(acct: string): Acct {
|
||||||
|
if (acct.startsWith("@")) acct = acct.slice(1);
|
||||||
|
const split = acct.split("@", 2);
|
||||||
|
return { username: split[0], host: split[1] || null };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toString(acct: Acct): string {
|
||||||
|
return acct.host == null ? acct.username : `${acct.username}@${acct.host}`;
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ import type { Note } from "@/models/entities/note.js";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import { Blockings, Followings, UserProfiles } from "@/models/index.js";
|
import { Blockings, Followings, UserProfiles } from "@/models/index.js";
|
||||||
import { getFullApAccount } from "@/misc/convert-host.js";
|
import { getFullApAccount } from "@/misc/convert-host.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import type { Packed } from "@/misc/schema.js";
|
import type { Packed } from "@/misc/schema.js";
|
||||||
import { Cache } from "@/misc/cache.js";
|
import { Cache } from "@/misc/cache.js";
|
||||||
import { getWordHardMute } from "@/misc/check-word-mute.js";
|
import { getWordHardMute } from "@/misc/check-word-mute.js";
|
||||||
|
@ -25,8 +25,8 @@ export async function checkHitAntenna(
|
||||||
|
|
||||||
if (antenna.src === "users") {
|
if (antenna.src === "users") {
|
||||||
const accts = antenna.users.map((x) => {
|
const accts = antenna.users.map((x) => {
|
||||||
const { username, host } = stringToAcct(x);
|
const { username, host } = Acct.parse(x);
|
||||||
return getFullApAccount(username, host ?? null).toLowerCase();
|
return getFullApAccount(username, host).toLowerCase();
|
||||||
});
|
});
|
||||||
if (
|
if (
|
||||||
!accts.includes(
|
!accts.includes(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type Bull from "bull";
|
import type Bull from "bull";
|
||||||
|
|
||||||
import { queueLogger } from "../../logger.js";
|
import { queueLogger } from "../../logger.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import { resolveUser } from "@/remote/resolve-user.js";
|
import { resolveUser } from "@/remote/resolve-user.js";
|
||||||
import { downloadTextFile } from "@/misc/download-text-file.js";
|
import { downloadTextFile } from "@/misc/download-text-file.js";
|
||||||
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
|
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
|
||||||
|
@ -41,7 +41,7 @@ export async function importBlocking(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const acct = line.split(",")[0].trim();
|
const acct = line.split(",")[0].trim();
|
||||||
const { username, host } = stringToAcct(acct);
|
const { username, host } = Acct.parse(acct);
|
||||||
|
|
||||||
let target = isSelfHost(host!)
|
let target = isSelfHost(host!)
|
||||||
? await Users.findOneBy({
|
? await Users.findOneBy({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { IsNull } from "typeorm";
|
import { IsNull } from "typeorm";
|
||||||
import follow from "@/services/following/create.js";
|
import follow from "@/services/following/create.js";
|
||||||
|
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import { resolveUser } from "@/remote/resolve-user.js";
|
import { resolveUser } from "@/remote/resolve-user.js";
|
||||||
import { downloadTextFile } from "@/misc/download-text-file.js";
|
import { downloadTextFile } from "@/misc/download-text-file.js";
|
||||||
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
|
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
|
||||||
|
@ -39,7 +39,7 @@ export async function importFollowing(
|
||||||
if (file.type.endsWith("json")) {
|
if (file.type.endsWith("json")) {
|
||||||
for (const acct of JSON.parse(csv)) {
|
for (const acct of JSON.parse(csv)) {
|
||||||
try {
|
try {
|
||||||
const { username, host } = stringToAcct(acct);
|
const { username, host } = Acct.parse(acct);
|
||||||
|
|
||||||
let target = isSelfHost(host!)
|
let target = isSelfHost(host!)
|
||||||
? await Users.findOneBy({
|
? await Users.findOneBy({
|
||||||
|
@ -77,7 +77,7 @@ export async function importFollowing(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const acct = line.split(",")[0].trim();
|
const acct = line.split(",")[0].trim();
|
||||||
const { username, host } = stringToAcct(acct);
|
const { username, host } = Acct.parse(acct);
|
||||||
|
|
||||||
let target = isSelfHost(host!)
|
let target = isSelfHost(host!)
|
||||||
? await Users.findOneBy({
|
? await Users.findOneBy({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type Bull from "bull";
|
import type Bull from "bull";
|
||||||
|
|
||||||
import { queueLogger } from "../../logger.js";
|
import { queueLogger } from "../../logger.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import { resolveUser } from "@/remote/resolve-user.js";
|
import { resolveUser } from "@/remote/resolve-user.js";
|
||||||
import { downloadTextFile } from "@/misc/download-text-file.js";
|
import { downloadTextFile } from "@/misc/download-text-file.js";
|
||||||
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
|
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
|
||||||
|
@ -42,7 +42,7 @@ export async function importMuting(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const acct = line.split(",")[0].trim();
|
const acct = line.split(",")[0].trim();
|
||||||
const { username, host } = stringToAcct(acct);
|
const { username, host } = Acct.parse(acct);
|
||||||
|
|
||||||
let target = isSelfHost(host!)
|
let target = isSelfHost(host!)
|
||||||
? await Users.findOneBy({
|
? await Users.findOneBy({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type Bull from "bull";
|
import type Bull from "bull";
|
||||||
|
|
||||||
import { queueLogger } from "../../logger.js";
|
import { queueLogger } from "../../logger.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import { resolveUser } from "@/remote/resolve-user.js";
|
import { resolveUser } from "@/remote/resolve-user.js";
|
||||||
import { pushUserToUserList } from "@/services/user-list/push.js";
|
import { pushUserToUserList } from "@/services/user-list/push.js";
|
||||||
import { downloadTextFile } from "@/misc/download-text-file.js";
|
import { downloadTextFile } from "@/misc/download-text-file.js";
|
||||||
|
@ -47,7 +47,7 @@ export async function importUserLists(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const listName = line.split(",")[0].trim();
|
const listName = line.split(",")[0].trim();
|
||||||
const { username, host } = stringToAcct(line.split(",")[1].trim());
|
const { username, host } = Acct.parse(line.split(",")[1].trim());
|
||||||
|
|
||||||
let list = await UserLists.findOneBy({
|
let list = await UserLists.findOneBy({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { DAY } from "@/const.js";
|
||||||
import { apiLogger } from "@/server/api/logger.js";
|
import { apiLogger } from "@/server/api/logger.js";
|
||||||
import define from "@/server/api/define.js";
|
import define from "@/server/api/define.js";
|
||||||
import { ApiError } from "@/server/api/error.js";
|
import { ApiError } from "@/server/api/error.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import { parse } from "@/misc/acct.js";
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ["users"],
|
tags: ["users"],
|
||||||
|
@ -71,9 +71,9 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
for (const line of ps.alsoKnownAs) {
|
for (const line of ps.alsoKnownAs) {
|
||||||
if (!line) throw new ApiError(meta.errors.noSuchUser);
|
if (!line) throw new ApiError(meta.errors.noSuchUser);
|
||||||
const { username, host } = stringToAcct(line);
|
const { username, host } = parse(line);
|
||||||
|
|
||||||
const aka = await resolveUser(username, host ?? null).catch((e) => {
|
const aka = await resolveUser(username, host).catch((e) => {
|
||||||
apiLogger.warn(`failed to resolve remote user: ${e}`);
|
apiLogger.warn(`failed to resolve remote user: ${e}`);
|
||||||
throw new ApiError(meta.errors.noSuchUser);
|
throw new ApiError(meta.errors.noSuchUser);
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { getUser } from "@/server/api/common/getters.js";
|
||||||
import { Followings, Users } from "@/models/index.js";
|
import { Followings, Users } from "@/models/index.js";
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
import { publishMainStream } from "@/services/stream.js";
|
import { publishMainStream } from "@/services/stream.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import { parse } from "@/misc/acct.js";
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ["users"],
|
tags: ["users"],
|
||||||
|
@ -89,10 +89,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
if (!ps.moveToAccount) throw new ApiError(meta.errors.noSuchMoveTarget);
|
if (!ps.moveToAccount) throw new ApiError(meta.errors.noSuchMoveTarget);
|
||||||
if (user.movedToUri) throw new ApiError(meta.errors.alreadyMoved);
|
if (user.movedToUri) throw new ApiError(meta.errors.alreadyMoved);
|
||||||
|
|
||||||
const { username, host } = stringToAcct(ps.moveToAccount);
|
const { username, host } = parse(ps.moveToAccount);
|
||||||
if (!host) throw new ApiError(meta.errors.notRemote);
|
if (!host) throw new ApiError(meta.errors.notRemote);
|
||||||
|
|
||||||
const moveTo: User = await resolveUser(username, host ?? null).catch((e) => {
|
const moveTo: User = await resolveUser(username, host).catch((e) => {
|
||||||
apiLogger.warn(`failed to resolve remote user: ${e}`);
|
apiLogger.warn(`failed to resolve remote user: ${e}`);
|
||||||
throw new ApiError(meta.errors.noSuchMoveTarget);
|
throw new ApiError(meta.errors.noSuchMoveTarget);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { IsNull } from "typeorm";
|
import { IsNull } from "typeorm";
|
||||||
import { Users } from "@/models/index.js";
|
import { Users } from "@/models/index.js";
|
||||||
import { fetchMeta } from "@/misc/fetch-meta.js";
|
import { fetchMeta } from "@/misc/fetch-meta.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import define from "@/server/api/define.js";
|
import define from "@/server/api/define.js";
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
|
|
||||||
const users = await Promise.all(
|
const users = await Promise.all(
|
||||||
meta.pinnedUsers
|
meta.pinnedUsers
|
||||||
.map((acct) => stringToAcct(acct))
|
.map((acct) => Acct.parse(acct))
|
||||||
.map((acct) =>
|
.map((acct) =>
|
||||||
Users.findOneBy({
|
Users.findOneBy({
|
||||||
usernameLower: acct.username.toLowerCase(),
|
usernameLower: acct.username.toLowerCase(),
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { Users } from "@/models/index.js";
|
||||||
import { fetchMeta } from "@/misc/fetch-meta.js";
|
import { fetchMeta } from "@/misc/fetch-meta.js";
|
||||||
import { genIdenticon } from "@/misc/gen-identicon.js";
|
import { genIdenticon } from "@/misc/gen-identicon.js";
|
||||||
import { createTemp } from "@/misc/create-temp.js";
|
import { createTemp } from "@/misc/create-temp.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import { envOption } from "@/env.js";
|
import { envOption } from "@/env.js";
|
||||||
import megalodon, { MegalodonInterface } from "megalodon";
|
import megalodon, { MegalodonInterface } from "megalodon";
|
||||||
import activityPub from "./activitypub.js";
|
import activityPub from "./activitypub.js";
|
||||||
|
@ -107,7 +107,7 @@ router.use(nodeinfo.routes());
|
||||||
router.use(wellKnown.routes());
|
router.use(wellKnown.routes());
|
||||||
|
|
||||||
router.get("/avatar/@:acct", async (ctx) => {
|
router.get("/avatar/@:acct", async (ctx) => {
|
||||||
const { username, host } = stringToAcct(ctx.params.acct);
|
const { username, host } = Acct.parse(ctx.params.acct);
|
||||||
const user = await Users.findOne({
|
const user = await Users.findOne({
|
||||||
where: {
|
where: {
|
||||||
usernameLower: username.toLowerCase(),
|
usernameLower: username.toLowerCase(),
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {
|
||||||
Emojis,
|
Emojis,
|
||||||
GalleryPosts,
|
GalleryPosts,
|
||||||
} from "@/models/index.js";
|
} from "@/models/index.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import { getNoteSummary } from "@/misc/get-note-summary.js";
|
import { getNoteSummary } from "@/misc/get-note-summary.js";
|
||||||
import { queues } from "@/queue/queues.js";
|
import { queues } from "@/queue/queues.js";
|
||||||
import { genOpenapiSpec } from "../api/openapi/gen-spec.js";
|
import { genOpenapiSpec } from "../api/openapi/gen-spec.js";
|
||||||
|
@ -328,7 +328,7 @@ const getFeed = async (
|
||||||
if (meta.privateMode) {
|
if (meta.privateMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { username, host } = stringToAcct(acct);
|
const { username, host } = Acct.parse(acct);
|
||||||
const user = await Users.findOneBy({
|
const user = await Users.findOneBy({
|
||||||
usernameLower: username.toLowerCase(),
|
usernameLower: username.toLowerCase(),
|
||||||
host: host ?? IsNull(),
|
host: host ?? IsNull(),
|
||||||
|
@ -459,7 +459,7 @@ const jsonFeed: Router.Middleware = async (ctx) => {
|
||||||
const userPage: Router.Middleware = async (ctx, next) => {
|
const userPage: Router.Middleware = async (ctx, next) => {
|
||||||
const userParam = ctx.params.user;
|
const userParam = ctx.params.user;
|
||||||
const subParam = ctx.params.sub;
|
const subParam = ctx.params.sub;
|
||||||
const { username, host } = stringToAcct(userParam);
|
const { username, host } = Acct.parse(userParam);
|
||||||
|
|
||||||
const user = await Users.findOneBy({
|
const user = await Users.findOneBy({
|
||||||
usernameLower: username.toLowerCase(),
|
usernameLower: username.toLowerCase(),
|
||||||
|
@ -578,7 +578,7 @@ router.get("/posts/:note", async (ctx, next) => {
|
||||||
|
|
||||||
// Page
|
// Page
|
||||||
router.get("/@:user/pages/:page", async (ctx, next) => {
|
router.get("/@:user/pages/:page", async (ctx, next) => {
|
||||||
const { username, host } = stringToAcct(ctx.params.user);
|
const { username, host } = Acct.parse(ctx.params.user);
|
||||||
const user = await Users.findOneBy({
|
const user = await Users.findOneBy({
|
||||||
usernameLower: username.toLowerCase(),
|
usernameLower: username.toLowerCase(),
|
||||||
host: host ?? IsNull(),
|
host: host ?? IsNull(),
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import Router from "@koa/router";
|
import Router from "@koa/router";
|
||||||
|
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
import { stringToAcct } from "native-utils/built/index.js";
|
import * as Acct from "@/misc/acct.js";
|
||||||
import type { Acct } from "native-utils/built/index.js";
|
|
||||||
import { links } from "./nodeinfo.js";
|
import { links } from "./nodeinfo.js";
|
||||||
import { escapeAttribute, escapeValue } from "@/prelude/xml.js";
|
import { escapeAttribute, escapeValue } from "@/prelude/xml.js";
|
||||||
import { Users } from "@/models/index.js";
|
import { Users } from "@/models/index.js";
|
||||||
|
@ -111,7 +110,7 @@ router.get(webFingerPath, async (ctx) => {
|
||||||
resource.startsWith(`${config.url.toLowerCase()}/users/`)
|
resource.startsWith(`${config.url.toLowerCase()}/users/`)
|
||||||
? fromId(resource.split("/").pop()!)
|
? fromId(resource.split("/").pop()!)
|
||||||
: fromAcct(
|
: fromAcct(
|
||||||
stringToAcct(
|
Acct.parse(
|
||||||
resource.startsWith(`${config.url.toLowerCase()}/@`)
|
resource.startsWith(`${config.url.toLowerCase()}/@`)
|
||||||
? resource.split("/").pop()!
|
? resource.split("/").pop()!
|
||||||
: resource.startsWith("acct:")
|
: resource.startsWith("acct:")
|
||||||
|
@ -120,7 +119,7 @@ router.get(webFingerPath, async (ctx) => {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const fromAcct = (acct: Acct): FindOptionsWhere<User> | number =>
|
const fromAcct = (acct: Acct.Acct): FindOptionsWhere<User> | number =>
|
||||||
!acct.host || acct.host === config.host.toLowerCase()
|
!acct.host || acct.host === config.host.toLowerCase()
|
||||||
? {
|
? {
|
||||||
usernameLower: acct.username,
|
usernameLower: acct.username,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
// import { sendEmail } from "./send-email.js";
|
// import { sendEmail } from "./send-email.js";
|
||||||
// import { I18n } from "@/misc/i18n.js";
|
// import { I18n } from "@/misc/i18n.js";
|
||||||
// import { acctToString } from "native-utils/built/index.js";
|
// import * as Acct from "@/misc/acct.js";
|
||||||
// TODO
|
// TODO
|
||||||
//const locales = await import('../../../../locales/index.js');
|
//const locales = await import('../../../../locales/index.js');
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ async function follow(userId: User["id"], follower: User) {
|
||||||
const locale = locales[userProfile.lang || 'ja-JP'];
|
const locale = locales[userProfile.lang || 'ja-JP'];
|
||||||
const i18n = new I18n(locale);
|
const i18n = new I18n(locale);
|
||||||
// TODO: render user information html
|
// TODO: render user information html
|
||||||
sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${acctToString(follower)})`, `${follower.name} (@${acctToString(follower)})`);
|
sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ async function receiveFollowRequest(userId: User["id"], follower: User) {
|
||||||
const locale = locales[userProfile.lang || 'ja-JP'];
|
const locale = locales[userProfile.lang || 'ja-JP'];
|
||||||
const i18n = new I18n(locale);
|
const i18n = new I18n(locale);
|
||||||
// TODO: render user information html
|
// TODO: render user information html
|
||||||
sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${acctToString(follower)})`, `${follower.name} (@${acctToString(follower)})`);
|
sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue