diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index a0619f4d0..6deb3bad9 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -372,12 +372,14 @@ export const UserRepository = db.getRepository(User).extend({ options?: { detail?: D; includeSecrets?: boolean; + isPrivateMode?: boolean; }, ): Promise> { const opts = Object.assign( { detail: false, includeSecrets: false, + isPrivateMode: false }, options, ); @@ -442,6 +444,30 @@ export const UserRepository = db.getRepository(User).extend({ const falsy = opts.detail ? false : undefined; + if (opts.isPrivateMode) { + const packed = { + id: user.id, + username: user.username, + host: user.host, + + ...(opts.detail + ? { + twoFactorEnabled: profile!.twoFactorEnabled, + usePasswordLessLogin: profile!.usePasswordLessLogin, + securityKeys: profile!.twoFactorEnabled + ? UserSecurityKeys.countBy({ + userId: user.id, + }).then((result) => result >= 1) + : false, + } + : {}), + } as Promiseable> as Promiseable< + IsMeAndIsUserDetailed + >; + + return await awaitAll(packed); + } + const packed = { id: user.id, name: user.name, @@ -472,7 +498,7 @@ export const UserRepository = db.getRepository(User).extend({ iconUrl: instance.iconUrl, faviconUrl: instance.faviconUrl, themeColor: instance.themeColor, - } + } : undefined, ) : undefined, @@ -527,9 +553,9 @@ export const UserRepository = db.getRepository(User).extend({ securityKeys: profile!.twoFactorEnabled ? UserSecurityKeys.countBy({ userId: user.id, - }).then((result) => result >= 1) + }).then((result) => result >= 1) : false, - } + } : {}), ...(opts.detail && isMe @@ -568,7 +594,7 @@ export const UserRepository = db.getRepository(User).extend({ mutedInstances: profile!.mutedInstances, mutingNotificationTypes: profile!.mutingNotificationTypes, emailNotificationTypes: profile!.emailNotificationTypes, - } + } : {}), ...(opts.includeSecrets @@ -585,9 +611,9 @@ export const UserRepository = db.getRepository(User).extend({ name: true, lastUsed: true, }, - }) + }) : [], - } + } : {}), ...(relation @@ -601,7 +627,7 @@ export const UserRepository = db.getRepository(User).extend({ isBlocked: relation.isBlocked, isMuted: relation.isMuted, isRenoteMuted: relation.isRenoteMuted, - } + } : {}), } as Promiseable> as Promiseable< IsMeAndIsUserDetailed diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index bead8df0a..6a03097ef 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -6,12 +6,14 @@ import type { User } from "@/models/entities/user.js"; import define from "../../define.js"; import { apiLogger } from "../../logger.js"; import { ApiError } from "../../error.js"; +import { fetchMeta } from "@/misc/fetch-meta.js"; export const meta = { tags: ["users"], + // TODO: determine if should allow this in private mode or to create a new endpoint just for 2fa requireCredential: false, - requireCredentialPrivateMode: true, + requireCredentialPrivateMode: false, // set to false to allow FIDO2 and other 2fa auth description: "Show the properties of a user.", @@ -146,8 +148,13 @@ export default define(meta, paramDef, async (ps, me) => { throw new ApiError(meta.errors.noSuchUser); } + // apiLogger.debug(`packed (detailed): ${JSON.stringify(await Users.pack(user, me, {detail: true}))}`); + // apiLogger.debug(`packed (private): ${JSON.stringify(await Users.pack(user, me, {detail: true, isPrivateMode: true}))}`); + + const serverMeta = await fetchMeta(); return await Users.pack(user, me, { detail: true, + isPrivateMode: me !== null ? false : serverMeta.privateMode }); } });