diff --git a/locales/de-DE.yml b/locales/de-DE.yml index d7920b361e..ea0fb88462 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -112,6 +112,7 @@ reactionSettingDescription2: "Ziehe um Anzuordnen, klicke um zu löschen, drück rememberNoteVisibility: "Notizsichtbarkeit merken" attachCancel: "Anhang entfernen" markAsSensitive: "Als NSFW markieren" +accountMoved: "Benutzer hat zu einem anderen Account gewechselt." unmarkAsSensitive: "Als nicht NSFW markieren" enterFileName: "Dateinamen eingeben" mute: "Stummschalten" diff --git a/locales/en-US.yml b/locales/en-US.yml index f5758ed645..1215055d59 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -149,6 +149,7 @@ addAccount: "Add account" loginFailed: "Failed to sign in" showOnRemote: "View on remote instance" general: "General" +accountMoved: "User has moved to a new account." wallpaper: "Wallpaper" setWallpaper: "Set wallpaper" removeWallpaper: "Remove wallpaper" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index b045f5448f..90820d43a2 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -149,6 +149,7 @@ addAccount: "アカウントを追加" loginFailed: "ログインに失敗しました" showOnRemote: "リモートで表示" general: "全般" +accountMoved: "このユーザーは新しいアカウントに移行しました" wallpaper: "壁紙" setWallpaper: "壁紙を設定" removeWallpaper: "壁紙を削除" diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index 5c46ae27a3..47ab1fc9e8 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -1,16 +1,38 @@ -import { EntityRepository, Repository, In, Not } from 'typeorm'; +import {In, Not} from 'typeorm'; import Ajv from 'ajv'; -import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js'; +import {ILocalUser, IRemoteUser, User} from '@/models/entities/user.js'; import config from '@/config/index.js'; -import { Packed } from '@/misc/schema.js'; -import { awaitAll, Promiseable } from '@/prelude/await-all.js'; -import { populateEmojis } from '@/misc/populate-emojis.js'; -import { getAntennas } from '@/misc/antenna-cache.js'; -import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js'; -import { Cache } from '@/misc/cache.js'; -import { db } from '@/db/postgre.js'; -import { Instance } from '../entities/instance.js'; -import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index.js'; +import {Packed} from '@/misc/schema.js'; +import {awaitAll, Promiseable} from '@/prelude/await-all.js'; +import {populateEmojis} from '@/misc/populate-emojis.js'; +import {getAntennas} from '@/misc/antenna-cache.js'; +import {USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD} from '@/const.js'; +import {Cache} from '@/misc/cache.js'; +import {db} from '@/db/postgre.js'; +import {Instance} from '../entities/instance.js'; +import {resolveUser} from "@/remote/resolve-user"; +import {URL} from "url"; +import { + AnnouncementReads, + Announcements, + AntennaNotes, + Blockings, + ChannelFollowings, + DriveFiles, + Followings, + FollowRequests, + Instances, + MessagingMessages, + Mutings, + Notes, + NoteUnreads, + Notifications, + Pages, + UserGroupJoinings, + UserNotePinings, + UserProfiles, + UserSecurityKeys +} from '../index.js'; const userInstanceCache = new Cache(1000 * 60 * 60 * 3); @@ -156,6 +178,23 @@ export const UserRepository = db.getRepository(User).extend({ return count > 0; }, + async userFromURI(uri: string): Promise { + if (uri.startsWith(config.url + '/')) { + const id = uri.split('/').pop(); + if (id == undefined) return null; + return await resolveUser(id, null); + } + + let url = new URL(uri); + let userTag = url.pathname; + + if (userTag.startsWith("@")) { + userTag = userTag.substring(1); + } + + return await resolveUser(userTag, url.host); + }, + async getHasUnreadAntenna(userId: User['id']): Promise { const myAntennas = (await getAntennas()).filter(a => a.userId === userId); @@ -320,6 +359,8 @@ export const UserRepository = db.getRepository(User).extend({ ...(opts.detail ? { url: profile!.url, uri: user.uri, + movedTo: user.movedToUri ? await this.userFromURI(user.movedToUri) : null, + alsoKnownAs: user.alsoKnownAs, createdAt: user.createdAt.toISOString(), updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null, diff --git a/packages/backend/src/models/schema/user.ts b/packages/backend/src/models/schema/user.ts index 218d861e5b..95827272f9 100644 --- a/packages/backend/src/models/schema/user.ts +++ b/packages/backend/src/models/schema/user.ts @@ -96,6 +96,16 @@ export const packedUserDetailedNotMeOnlySchema = { format: 'uri', nullable: true, optional: false, }, + movedTo: { + type: 'string', + format: 'uri', + nullable: true, optional: false, + }, + alsoKnownAs: { + type: 'array', + format: 'uri', + nullable: true, optional: false, + }, createdAt: { type: 'string', nullable: false, optional: false, diff --git a/packages/client/src/components/MkMoved.vue b/packages/client/src/components/MkMoved.vue new file mode 100644 index 0000000000..f5ec1a567e --- /dev/null +++ b/packages/client/src/components/MkMoved.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue index b0ff75eefe..e8e111caea 100644 --- a/packages/client/src/pages/user/home.vue +++ b/packages/client/src/pages/user/home.vue @@ -8,6 +8,7 @@
+