added more selective control over users show endpoint

This commit is contained in:
Alexis 2023-11-08 16:03:03 -05:00 committed by Laura Hausmann
parent 84e8e095ec
commit 76db23855c
Signed by: zotan
GPG key ID: D044E84C5BE01605
2 changed files with 41 additions and 8 deletions

View file

@ -372,12 +372,14 @@ export const UserRepository = db.getRepository(User).extend({
options?: { options?: {
detail?: D; detail?: D;
includeSecrets?: boolean; includeSecrets?: boolean;
isPrivateMode?: boolean;
}, },
): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> { ): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> {
const opts = Object.assign( const opts = Object.assign(
{ {
detail: false, detail: false,
includeSecrets: false, includeSecrets: false,
isPrivateMode: false
}, },
options, options,
); );
@ -442,6 +444,30 @@ export const UserRepository = db.getRepository(User).extend({
const falsy = opts.detail ? false : undefined; 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<Packed<"User">> as Promiseable<
IsMeAndIsUserDetailed<ExpectsMe, D>
>;
return await awaitAll(packed);
}
const packed = { const packed = {
id: user.id, id: user.id,
name: user.name, name: user.name,
@ -472,7 +498,7 @@ export const UserRepository = db.getRepository(User).extend({
iconUrl: instance.iconUrl, iconUrl: instance.iconUrl,
faviconUrl: instance.faviconUrl, faviconUrl: instance.faviconUrl,
themeColor: instance.themeColor, themeColor: instance.themeColor,
} }
: undefined, : undefined,
) )
: undefined, : undefined,
@ -527,9 +553,9 @@ export const UserRepository = db.getRepository(User).extend({
securityKeys: profile!.twoFactorEnabled securityKeys: profile!.twoFactorEnabled
? UserSecurityKeys.countBy({ ? UserSecurityKeys.countBy({
userId: user.id, userId: user.id,
}).then((result) => result >= 1) }).then((result) => result >= 1)
: false, : false,
} }
: {}), : {}),
...(opts.detail && isMe ...(opts.detail && isMe
@ -568,7 +594,7 @@ export const UserRepository = db.getRepository(User).extend({
mutedInstances: profile!.mutedInstances, mutedInstances: profile!.mutedInstances,
mutingNotificationTypes: profile!.mutingNotificationTypes, mutingNotificationTypes: profile!.mutingNotificationTypes,
emailNotificationTypes: profile!.emailNotificationTypes, emailNotificationTypes: profile!.emailNotificationTypes,
} }
: {}), : {}),
...(opts.includeSecrets ...(opts.includeSecrets
@ -585,9 +611,9 @@ export const UserRepository = db.getRepository(User).extend({
name: true, name: true,
lastUsed: true, lastUsed: true,
}, },
}) })
: [], : [],
} }
: {}), : {}),
...(relation ...(relation
@ -601,7 +627,7 @@ export const UserRepository = db.getRepository(User).extend({
isBlocked: relation.isBlocked, isBlocked: relation.isBlocked,
isMuted: relation.isMuted, isMuted: relation.isMuted,
isRenoteMuted: relation.isRenoteMuted, isRenoteMuted: relation.isRenoteMuted,
} }
: {}), : {}),
} as Promiseable<Packed<"User">> as Promiseable< } as Promiseable<Packed<"User">> as Promiseable<
IsMeAndIsUserDetailed<ExpectsMe, D> IsMeAndIsUserDetailed<ExpectsMe, D>

View file

@ -6,12 +6,14 @@ import type { User } from "@/models/entities/user.js";
import define from "../../define.js"; import define from "../../define.js";
import { apiLogger } from "../../logger.js"; import { apiLogger } from "../../logger.js";
import { ApiError } from "../../error.js"; import { ApiError } from "../../error.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
export const meta = { export const meta = {
tags: ["users"], tags: ["users"],
// TODO: determine if should allow this in private mode or to create a new endpoint just for 2fa
requireCredential: false, requireCredential: false,
requireCredentialPrivateMode: true, requireCredentialPrivateMode: false, // set to false to allow FIDO2 and other 2fa auth
description: "Show the properties of a user.", 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); 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, { return await Users.pack(user, me, {
detail: true, detail: true,
isPrivateMode: me !== null ? false : serverMeta.privateMode
}); });
} }
}); });