From 9a46c3a7128fbc448abe87752fcae36cf2f62753 Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Sun, 19 Apr 2026 11:17:44 +0200 Subject: [PATCH] fix: expose only public properties --- src/api/routes/users/#user_id/profile.ts | 29 +++++++++++++++++-- .../PartialConnectedAccountResponse.ts | 25 ++++++++++++++++ src/schemas/responses/index.ts | 1 + 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/schemas/responses/PartialConnectedAccountResponse.ts diff --git a/src/api/routes/users/#user_id/profile.ts b/src/api/routes/users/#user_id/profile.ts index c6a55201a..64e09bb68 100644 --- a/src/api/routes/users/#user_id/profile.ts +++ b/src/api/routes/users/#user_id/profile.ts @@ -20,7 +20,7 @@ import { route } from "@spacebar/api"; import { Badge, Config, emitEvent, FieldErrors, handleFile, Member, Relationship, User, UserUpdateEvent } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { In } from "typeorm"; -import { PrivateUserProjection, PublicUser, PublicUserProjection, RelationshipType, UserProfileModifySchema } from "@spacebar/schemas"; +import { PartialConnectedAccountResponse, PrivateUserProjection, PublicUser, PublicUserProjection, RelationshipType, UserProfileModifySchema } from "@spacebar/schemas"; const router: Router = Router({ mergeParams: true }); @@ -123,8 +123,33 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), } } + // Only expose public propeties to response + const publicUserConnections: PartialConnectedAccountResponse[] = []; + + user.connected_accounts + .filter((x) => x.visibility != 0) + .map((x) => { + const publicUserConnection = { + id: x.id, + type: x.type, + name: x.name, + verified: x.verified ?? false, + } satisfies PartialConnectedAccountResponse; + + if (x.verified) { + publicUserConnection.verified = x.verified; + } + + if (x.metadata_visibility != 0) { + // @ts-expect-error idk + x.metadata = x.metadata_; + } + + publicUserConnections.push(publicUserConnection); + }); + res.json({ - connected_accounts: user.connected_accounts.filter((x) => x.visibility != 0), + connected_accounts: publicUserConnections, premium_guild_since: premium_guild_since, // TODO premium_since: user.premium_since, // TODO mutual_guilds: with_mutual_guilds ? mutual_guilds : undefined, // TODO {id: "", nick: null} when ?with_mutual_guilds=true diff --git a/src/schemas/responses/PartialConnectedAccountResponse.ts b/src/schemas/responses/PartialConnectedAccountResponse.ts new file mode 100644 index 000000000..d5d3ee844 --- /dev/null +++ b/src/schemas/responses/PartialConnectedAccountResponse.ts @@ -0,0 +1,25 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2026 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +export interface PartialConnectedAccountResponse { + id: string; + type: string; + name: string; + verified: boolean; + metadata?: object; +} diff --git a/src/schemas/responses/index.ts b/src/schemas/responses/index.ts index 690b1ec53..e231879e8 100644 --- a/src/schemas/responses/index.ts +++ b/src/schemas/responses/index.ts @@ -49,6 +49,7 @@ export * from "./InstanceStatsResponse"; export * from "./LocationMetadataResponse"; export * from "./MemberJoinGuildResponse"; export * from "./OAuthAuthorizeResponse"; +export * from "./PartialConnectedAccountResponse"; export * from "./PreloadMessagesResponseSchema"; export * from "./RefreshUrlsResponse"; export * from "./SettingsProtoUpdateResponse";