diff --git a/src/api/routes/users/@me/pomelo-attempt.ts b/src/api/routes/users/@me/pomelo-attempt.ts
new file mode 100644
index 00000000..d4327f61
--- /dev/null
+++ b/src/api/routes/users/@me/pomelo-attempt.ts
@@ -0,0 +1,35 @@
+import { route } from "@spacebar/api";
+import { Config, UniqueUsernameAttemptSchema, User } from "@spacebar/util";
+import { Request, Response, Router } from "express";
+import { HTTPError } from "lambert-server";
+const router = Router();
+
+// https://discord-userdoccers.vercel.app/resources/user#get-pomelo-eligibility
+router.post(
+ "/",
+ route({
+ requestBody: "UniqueUsernameAttemptSchema",
+ responses: {
+ 200: { body: "UniqueUsernameAttemptResponse" },
+ 400: { body: "APIErrorResponse" },
+ },
+ description:
+ "Checks whether a unique username is available for the user to claim.",
+ }),
+ async (req: Request, res: Response) => {
+ const body = req.body as UniqueUsernameAttemptSchema;
+ const { uniqueUsernames } = Config.get().general;
+ if (!uniqueUsernames) {
+ throw new HTTPError(
+ "Unique Usernames feature is not enabled on this instance.",
+ 400,
+ );
+ }
+
+ res.json({
+ taken: !(await User.isUsernameAvailable(body.username)),
+ });
+ },
+);
+
+export default router;
diff --git a/src/api/routes/users/@me/pomelo-suggestions.ts b/src/api/routes/users/@me/pomelo-suggestions.ts
new file mode 100644
index 00000000..c70336bf
--- /dev/null
+++ b/src/api/routes/users/@me/pomelo-suggestions.ts
@@ -0,0 +1,37 @@
+import { route } from "@spacebar/api";
+import { Config, User } from "@spacebar/util";
+import { Request, Response, Router } from "express";
+import { HTTPError } from "lambert-server";
+const router = Router();
+
+// https://discord-userdoccers.vercel.app/resources/user#get-pomelo-suggestions
+router.get(
+ "/",
+ route({
+ description:
+ "Returns a suggested unique username string based on the current user's username.",
+ responses: {
+ 400: { body: "APIErrorResponse" },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const { uniqueUsernames } = Config.get().general;
+ if (!uniqueUsernames) {
+ throw new HTTPError(
+ "Unique Usernames feature is not enabled on this instance.",
+ 400,
+ );
+ }
+
+ const user = await User.findOneOrFail({
+ where: {
+ id: req.user_id,
+ },
+ });
+
+ // TODO: return a suggestion based on the users current username
+ return res.json({ username: user.username.toString() });
+ },
+);
+
+export default router;
diff --git a/src/api/routes/users/@me/pomelo.ts b/src/api/routes/users/@me/pomelo.ts
new file mode 100644
index 00000000..e10beaa4
--- /dev/null
+++ b/src/api/routes/users/@me/pomelo.ts
@@ -0,0 +1,61 @@
+import { route } from "@spacebar/api";
+import {
+ Config,
+ FieldErrors,
+ UniqueUsernameAttemptSchema,
+ User,
+} from "@spacebar/util";
+import { Request, Response, Router } from "express";
+import { HTTPError } from "lambert-server";
+const router = Router();
+
+// https://discord-userdoccers.vercel.app/resources/user#create-pomelo-migration
+router.post(
+ "/",
+ route({
+ description:
+ "Claims a unique username for the user. Returns the updated user object on success. Fires a User Update Gateway event.",
+ requestBody: "UniqueUsernameAttemptSchema",
+ responses: {
+ 200: { body: "PrivateUserResponse" },
+ 400: { body: "APIErrorResponse" },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const body = req.body as UniqueUsernameAttemptSchema;
+ const { uniqueUsernames } = Config.get().general;
+ if (!uniqueUsernames) {
+ throw new HTTPError(
+ "Unique Usernames feature is not enabled on this instance.",
+ 400,
+ );
+ }
+
+ const isAvailable = await User.isUsernameAvailable(body.username);
+
+ if (!isAvailable) {
+ throw FieldErrors({
+ username: {
+ code: "USERNAME_TOO_MANY_USERS",
+ message:
+ req?.t("auth:register.USERNAME_TOO_MANY_USERS") || "",
+ },
+ });
+ }
+
+ const user = await User.findOneOrFail({
+ where: {
+ id: req.user_id,
+ },
+ });
+
+ user.legacy_username = user.username;
+ user.username = body.username;
+ user.discriminator = "0";
+ const newUser = await user.save();
+
+ res.json(newUser.toPrivateUser());
+ },
+);
+
+export default router;
|