summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPuyodead1 <puyodead@protonmail.com>2023-05-05 11:09:05 -0400
committerPuyodead1 <puyodead@protonmail.com>2023-12-23 16:30:58 -0500
commit9f4f7cac6512330481ea3e2de0633fc893788c33 (patch)
tree54ac0220deba5a54c86d1a1b3b2a9369d926567b /src
parentupdate schemas.json and openapi.json (diff)
downloadserver-9f4f7cac6512330481ea3e2de0633fc893788c33.tar.xz
initial pomelo implementation
Diffstat (limited to 'src')
-rw-r--r--src/api/routes/auth/forgot.ts2
-rw-r--r--src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts1
-rw-r--r--src/api/routes/channels/#channel_id/messages/index.ts5
-rw-r--r--src/api/routes/guilds/#guild_id/bans.ts2
-rw-r--r--src/api/routes/guilds/#guild_id/messages/search.ts2
-rw-r--r--src/api/routes/oauth2/authorize.ts6
-rw-r--r--src/api/routes/users/#id/relationships.ts2
-rw-r--r--src/api/routes/users/@me/index.ts2
-rw-r--r--src/api/routes/users/@me/relationships.ts21
-rw-r--r--src/connections/Discord/index.ts3
-rw-r--r--src/util/config/types/GeneralConfiguration.ts1
-rw-r--r--src/util/dtos/UserDTO.ts16
-rw-r--r--src/util/entities/User.ts47
-rw-r--r--src/util/schemas/RelationshipPostSchema.ts1
-rw-r--r--src/util/schemas/responses/GuildBansResponse.ts2
-rw-r--r--src/util/schemas/responses/GuildWidgetJsonResponse.ts2
-rw-r--r--src/util/schemas/responses/UserRelationsResponse.ts2
-rw-r--r--src/util/util/email/index.ts3
18 files changed, 93 insertions, 27 deletions
diff --git a/src/api/routes/auth/forgot.ts b/src/api/routes/auth/forgot.ts

index 6fa86021..7a791164 100644 --- a/src/api/routes/auth/forgot.ts +++ b/src/api/routes/auth/forgot.ts
@@ -111,7 +111,7 @@ router.post( }) .catch((e) => { console.error( - `Failed to send password reset email to ${user.username}#${user.discriminator}: ${e}`, + `Failed to send password reset email to ${user.handle}: ${e}`, ); throw new HTTPError("Failed to send password reset email", 500); }); diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts
index 5ca645c0..ed2670ca 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts
@@ -43,6 +43,7 @@ router.post( username: "", avatar: "", discriminator: "", + global_name: "", public_flags: 64, }, attachments: [], diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts
index a5bfcfd7..8b028f43 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts
@@ -171,11 +171,14 @@ router.get( if ((y.user_ids || []).includes(req.user_id)) y.me = true; delete y.user_ids; }); + const { pomeloEnabled } = Config.get().general; if (!x.author) x.author = User.create({ id: "4", - discriminator: "0000", + discriminator: pomeloEnabled ? "0" : "0000", username: "Spacebar Ghost", + global_name: "spacebarghost", + display_name: "Spacebar Ghost", public_flags: 0, }); x.attachments?.forEach((y: Attachment) => { diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts
index 9aeb27f0..ede9f4bd 100644 --- a/src/api/routes/guilds/#guild_id/bans.ts +++ b/src/api/routes/guilds/#guild_id/bans.ts
@@ -70,6 +70,8 @@ router.get( user: { username: user.username, discriminator: user.discriminator, + global_name: user.global_name, + display_name: user.display_name, id: user.id, avatar: user.avatar, public_flags: user.public_flags, diff --git a/src/api/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts
index 637d1e43..bf5fc4cd 100644 --- a/src/api/routes/guilds/#guild_id/messages/search.ts +++ b/src/api/routes/guilds/#guild_id/messages/search.ts
@@ -149,6 +149,8 @@ router.get( avatar: x.author?.avatar, avatar_decoration: null, discriminator: x.author?.discriminator, + global_name: x.author?.global_name, + display_name: x.author?.display_name, public_flags: x.author?.public_flags, }, attachments: x.attachments, diff --git a/src/api/routes/oauth2/authorize.ts b/src/api/routes/oauth2/authorize.ts
index 2f2351f3..11255b98 100644 --- a/src/api/routes/oauth2/authorize.ts +++ b/src/api/routes/oauth2/authorize.ts
@@ -89,6 +89,8 @@ router.get( "username", "avatar", "discriminator", + "global_name", + "display_name", "public_flags", ], }); @@ -137,6 +139,8 @@ router.get( avatar: user.avatar, avatar_decoration: null, // TODO discriminator: user.discriminator, + global_name: user.global_name, + display_name: user.display_name, public_flags: user.public_flags, }, application: { @@ -159,6 +163,8 @@ router.get( avatar: bot.avatar, avatar_decoration: null, // TODO discriminator: bot.discriminator, + global_name: bot.global_name, + display_name: bot.display_name, public_flags: bot.public_flags, bot: true, approximated_guild_count: 0, // TODO diff --git a/src/api/routes/users/#id/relationships.ts b/src/api/routes/users/#id/relationships.ts
index 3737ca00..0008e75d 100644 --- a/src/api/routes/users/#id/relationships.ts +++ b/src/api/routes/users/#id/relationships.ts
@@ -58,6 +58,8 @@ router.get( username: relation_user.username, avatar: relation_user.avatar, discriminator: relation_user.discriminator, + global_name: relation_user.global_name, + display_name: relation_user.display_name, public_flags: relation_user.public_flags, }); } diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts
index ad11a428..1d209542 100644 --- a/src/api/routes/users/@me/index.ts +++ b/src/api/routes/users/@me/index.ts
@@ -140,6 +140,7 @@ router.patch( newToken = (await generateToken(user.id)) as string; } + // TODO: pomelo: disallow if pomelo is enabled if (body.username) { const check_username = body?.username?.replace(/\s/g, ""); if (!check_username) { @@ -162,6 +163,7 @@ router.patch( } } + // TODO: pomelo: disallow if pomelo is enabled if (body.discriminator) { if ( await User.findOne({ diff --git a/src/api/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts
index bce0a654..08342602 100644 --- a/src/api/routes/users/@me/relationships.ts +++ b/src/api/routes/users/@me/relationships.ts
@@ -114,19 +114,26 @@ router.post( }, }), async (req: Request, res: Response) => { + const { pomeloEnabled } = Config.get().general; + const where = pomeloEnabled + ? { + // TODO: pomelo: should we use username or add global_name property to the request? + global_name: req.body.username, + } + : { + discriminator: String(req.body.discriminator).padStart( + 4, + "0", + ), //Discord send the discriminator as integer, we need to add leading zeroes + username: req.body.username, + }; return await updateRelationship( req, res, await User.findOneOrFail({ relations: ["relationships", "relationships.to"], select: userProjection, - where: { - discriminator: String(req.body.discriminator).padStart( - 4, - "0", - ), //Discord send the discriminator as integer, we need to add leading zeroes - username: req.body.username, - }, + where, }), req.body.type, ); diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts
index 731086f1..206aa671 100644 --- a/src/connections/Discord/index.ts +++ b/src/connections/Discord/index.ts
@@ -31,6 +31,8 @@ interface UserResponse { id: string; username: string; discriminator: string; + global_name: string; + display_name?: string; avatar_url: string | null; } @@ -128,6 +130,7 @@ export default class DiscordConnection extends Connection { if (exists) return null; + // TODO: pomelo return await this.createConnection({ user_id: userId, external_id: userInfo.id, diff --git a/src/util/config/types/GeneralConfiguration.ts b/src/util/config/types/GeneralConfiguration.ts
index cff8c527..df3dfbcd 100644 --- a/src/util/config/types/GeneralConfiguration.ts +++ b/src/util/config/types/GeneralConfiguration.ts
@@ -29,4 +29,5 @@ export class GeneralConfiguration { image: string | null = null; instanceId: string = Snowflake.generate(); autoCreateBotUsers: boolean = false; + pomeloEnabled: boolean = false; } diff --git a/src/util/dtos/UserDTO.ts b/src/util/dtos/UserDTO.ts
index a24c8d96..5687bcef 100644 --- a/src/util/dtos/UserDTO.ts +++ b/src/util/dtos/UserDTO.ts
@@ -19,17 +19,21 @@ import { User } from "../entities"; export class MinimalPublicUserDTO { - avatar?: string | null; - discriminator: string; id: string; - public_flags: number; username: string; + global_name: string; + display_name?: string; + discriminator: string; + public_flags: number; + avatar?: string | null; constructor(user: User) { - this.avatar = user.avatar; - this.discriminator = user.discriminator; this.id = user.id; - this.public_flags = user.public_flags; this.username = user.username; + this.global_name = user.global_name; + this.display_name = user.display_name; + this.discriminator = user.discriminator; + this.public_flags = user.public_flags; + this.avatar = user.avatar; } } diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index c6582b00..0620640b 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts
@@ -37,6 +37,8 @@ import { UserSettings } from "./UserSettings"; export enum PublicUserEnum { username, + global_name, + display_name, discriminator, id, public_flags, @@ -90,8 +92,14 @@ export class User extends BaseClass { @Column() username: string; // username max length 32, min 2 (should be configurable) + @Column({nullable: true}) + global_name: string; // puyo: pomelo + + @Column({nullable: true}) + display_name?: string; // puyo: pomelo + @Column() - discriminator: string; // opaque string: 4 digits on discord.com + discriminator: string; // opaque string: 4 digits on discord.com, 0 for pomelo @Column({ nullable: true }) avatar?: string; // hash of the user avatar @@ -323,6 +331,13 @@ export class User extends BaseClass { } } + public get handle(): string { + const {pomeloEnabled} = Config.get().general; + + // if pomelo is enabled, global_name should be set + return pomeloEnabled ? this.global_name as string : `${this.username}#${this.discriminator}`; + } + static async register({ email, username, @@ -337,19 +352,25 @@ export class User extends BaseClass { id?: string; req?: Request; }) { + const {pomeloEnabled} = Config.get().general; + // trim special uf8 control characters -> Backspace, Newline, ... username = trimSpecial(username); - const discriminator = await User.generateDiscriminator(username); - if (!discriminator) { - // We've failed to generate a valid and unused discriminator - throw FieldErrors({ - username: { - code: "USERNAME_TOO_MANY_USERS", - message: - req?.t("auth:register.USERNAME_TOO_MANY_USERS") || "", - }, - }); + let discriminator: string | undefined; + if(pomeloEnabled) discriminator = "0"; + else { + discriminator = await User.generateDiscriminator(username); + if (!discriminator) { + // We've failed to generate a valid and unused discriminator + throw FieldErrors({ + username: { + code: "USERNAME_TOO_MANY_USERS", + message: + req?.t("auth:register.USERNAME_TOO_MANY_USERS") || "", + }, + }); + } } // TODO: save date_of_birth @@ -364,6 +385,8 @@ export class User extends BaseClass { const user = User.create({ username: username, + global_name: username, // TODO: convert to lowercase, strip special characters,etc??? + // display_name: username, // TODO: how should we do this? discriminator, id: id || Snowflake.generate(), email: email, @@ -391,7 +414,7 @@ export class User extends BaseClass { if (!Config.get().defaults.user.verified && email) { await Email.sendVerifyEmail(user, email).catch((e) => { console.error( - `Failed to send verification email to ${user.username}#${user.discriminator}: ${e}`, + `Failed to send verification email to ${user.handle}: ${e}`, ); }); } diff --git a/src/util/schemas/RelationshipPostSchema.ts b/src/util/schemas/RelationshipPostSchema.ts
index 066ecfd8..f0a5fc32 100644 --- a/src/util/schemas/RelationshipPostSchema.ts +++ b/src/util/schemas/RelationshipPostSchema.ts
@@ -16,6 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ +// TODO: pomelo? export interface RelationshipPostSchema { discriminator: string; username: string; diff --git a/src/util/schemas/responses/GuildBansResponse.ts b/src/util/schemas/responses/GuildBansResponse.ts
index 77c95a48..aa53105d 100644 --- a/src/util/schemas/responses/GuildBansResponse.ts +++ b/src/util/schemas/responses/GuildBansResponse.ts
@@ -21,6 +21,8 @@ export interface GuildBansResponse { user: { username: string; discriminator: string; + global_name: string; + display_name: string | null; id: string; avatar: string | null; public_flags: number; diff --git a/src/util/schemas/responses/GuildWidgetJsonResponse.ts b/src/util/schemas/responses/GuildWidgetJsonResponse.ts
index bd692304..60e8e7cc 100644 --- a/src/util/schemas/responses/GuildWidgetJsonResponse.ts +++ b/src/util/schemas/responses/GuildWidgetJsonResponse.ts
@@ -30,6 +30,8 @@ export interface GuildWidgetJsonResponse { members: { id: string; username: string; + global_name: string; + display_name: string | null; discriminator: string; avatar: string | null; status: ClientStatus; diff --git a/src/util/schemas/responses/UserRelationsResponse.ts b/src/util/schemas/responses/UserRelationsResponse.ts
index 808dd3d3..59db277f 100644 --- a/src/util/schemas/responses/UserRelationsResponse.ts +++ b/src/util/schemas/responses/UserRelationsResponse.ts
@@ -19,6 +19,8 @@ import { User } from "@spacebar/util"; export type UserRelationsResponse = (Pick<User, "id"> & Pick<User, "username"> & + Pick<User, "global_name"> & + Pick<User, "display_name"> & Pick<User, "discriminator"> & Pick<User, "avatar"> & Pick<User, "public_flags">)[]; diff --git a/src/util/util/email/index.ts b/src/util/util/email/index.ts
index 619cc5c3..6d34e234 100644 --- a/src/util/util/email/index.ts +++ b/src/util/util/email/index.ts
@@ -112,9 +112,12 @@ export const Email: { ) { const { instanceName } = Config.get().general; + // TODO: pomelo: display_name should take precedence over username if pomelo is enabled. maybe we should use global_name as the username? const replacements = [ ["{instanceName}", instanceName], ["{userUsername}", user.username], + ["{userGlobalName}", user.global_name], + ["{userDisplayName}", user.display_name], ["{userDiscriminator}", user.discriminator], ["{userId}", user.id], ["{phoneNumber}", user.phone?.slice(-4)],