diff --git a/app/routes/data-transfer.tsx b/app/routes/data-transfer.tsx
deleted file mode 100644
index 3a90f66..0000000
--- a/app/routes/data-transfer.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Button, Container, Heading, Text } from "@chakra-ui/react";
-
-export default function () {
- return (
-
- Transfer your Save Data
-
-
- Lost your account? Want to shake off a stalker?
-
-
- We can help!
-
-
- Some information you should know:
-
-
- We might require your .ROBLOSECURITY cookie, depending on your
- circumstances. This is because Roblox does not allow terminated accounts
- to utilize OAuth. Normally this would be a very bad idea, and we don't
- like doing this either, but it may be the only option. Security is also
- less of a concern for terminated accounts as they are blocked from
- accessing almost all Roblox API endpoints (the exceptions being login,
- logout, and creating support tickets - and only the logout endpoint
- doesn't require completing a captcha). If you are concerned about your
- account's security, we suggest logging in to your terminated account in
- a private/incognito window, copying the .ROBLOSECURITY cookie from
- there, and logging out once we have verified your old account (which
- normally only takes a few seconds). The ultra paranoid may also consider
- resetting their password. If you are not convinced or still have
- questions, join our Discord server (link is on the about page) and open
- a ticket with ModMail for us to verify you manually (no cookie
- required).
-
-
-
-
-
- );
-}
diff --git a/app/routes/data-transfer_.complete.tsx b/app/routes/data-transfer_.complete.tsx
deleted file mode 100644
index c8e7931..0000000
--- a/app/routes/data-transfer_.complete.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import Success from "../../components/Success.js";
-
-export default function () {
- return (
-
- );
-}
diff --git a/app/routes/data-transfer_.destination-account.tsx b/app/routes/data-transfer_.destination-account.tsx
deleted file mode 100644
index 18b0d77..0000000
--- a/app/routes/data-transfer_.destination-account.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Button, Card, Container, Heading, VStack } from "@chakra-ui/react";
-import { useLoaderData } from "@remix-run/react";
-
-export async function loader({ context }: { context: RequestContext }) {
- const { host, protocol } = new URL(context.request.url);
-
- return { client_id: context.env.ROBLOX_OAUTH_CLIENT_ID, host, protocol };
-}
-
-export default function () {
- const loaderData = useLoaderData();
- return (
-
-
-
- Verify your new Roblox account
-
-
-
-
-
- );
-}
diff --git a/app/routes/data-transfer_.start.tsx b/app/routes/data-transfer_.start.tsx
deleted file mode 100644
index dbd60c0..0000000
--- a/app/routes/data-transfer_.start.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import {
- Button,
- Container,
- Heading,
- HStack,
- Radio,
- RadioGroup,
- Text,
- Textarea,
- useToast,
-} from "@chakra-ui/react";
-import { useState } from "react";
-
-export default function () {
- const [showCookieBox, setShowCookieBox] = useState(false);
- const [loading, setLoading] = useState(false);
- return (
-
- Let's get started
- Is your old Roblox account banned?
- setShowCookieBox(JSON.parse(val))}>
-
- No
- Yes
-
-
-
-
-
-
- If you cannot login at all, please visit the support page and join our
- server.
-
-
- );
-}
diff --git a/functions/api/data-transfers/_middleware.ts b/functions/api/data-transfers/_middleware.ts
deleted file mode 100644
index 024189e..0000000
--- a/functions/api/data-transfers/_middleware.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-export async function onRequest(context: RequestContext) {
- const cookies = context.request.headers.get("cookie");
-
- if (!cookies) return await context.next();
-
- const cookieList = cookies.split("; ").map((cookie: string) => {
- const [name, value] = cookie.split("=");
-
- return { name, value };
- });
-
- const transferId = cookieList.find(
- (cookie: { name: string; value: string }) => cookie.name === "__dtid",
- );
-
- if (transferId) context.data.data_transfer_id = transferId;
-
- return await context.next();
-}
diff --git a/functions/api/data-transfers/create.ts b/functions/api/data-transfers/create.ts
deleted file mode 100644
index bd8e25d..0000000
--- a/functions/api/data-transfers/create.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import { jsonError } from "../../common.js";
-
-export async function onRequestPost(context: RequestContext) {
- const { cookie, is_banned } = context.data.body;
-
- if (
- typeof is_banned !== "boolean" ||
- (is_banned && typeof cookie !== "string") ||
- (is_banned &&
- !cookie.match(
- /_\|WARNING:-DO-NOT-SHARE-THIS\.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items\.\|_[A-F\d]+/,
- ))
- )
- return jsonError("Invalid request", 400);
-
- const id =
- (context.request.headers.get("cf-ray")?.split("-")[0] as string) +
- Date.now().toString() +
- crypto.randomUUID().replaceAll("-", "");
-
- if (!is_banned) {
- await context.env.DATA.put(`datatransfer_${id}`, "{}", {
- expirationTtl: 3600,
- });
-
- const host = context.request.headers.get("Host") as string;
-
- return new Response(
- `{"url":"https://apis.roblox.com/oauth/v1/authorize?client_id=${
- context.env.ROBLOX_OAUTH_CLIENT_ID
- }&redirect_uri=${encodeURIComponent(
- `http${host.startsWith(
- "localhost" ? "" : "s",
- )}://${host}/api/data-transfers/verify`,
- )}"}`,
- {
- headers: {
- "set-cookie": `__dtid=${id}; HttpOnly; Max-Age=3600; Path=/; SameSite=Lax; Secure`,
- },
- },
- );
- }
-
- const authedUserReq = await fetch(
- "https://users.roblox.com/v1/users/authenticated",
- {
- headers: {
- cookie: `.ROBLOSECURITY=${cookie}`,
- },
- },
- );
-
- if (!authedUserReq.ok) return jsonError("Cookie is invalid", 400);
-
- const authedUser: { id: number; name: string } = await authedUserReq.json();
-
- await context.env.DATA.put(
- `datatransfer_${id}`,
- JSON.stringify({
- oldUser: authedUser,
- }),
- {
- expirationTtl: 3600,
- },
- );
-
- return new Response(null, {
- headers: {
- location: "/data-transfer/destination-account",
- "set-cookie": `__dtid=${id}; HttpOnly; Max-Age=3600; Path=/; SameSite=Lax; Secure`,
- },
- status: 201,
- });
-}
diff --git a/functions/api/data-transfers/verify.ts b/functions/api/data-transfers/verify.ts
deleted file mode 100644
index 0a5e8af..0000000
--- a/functions/api/data-transfers/verify.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import { jsonError } from "../../common.js";
-import { getBanList } from "../../roblox-open-cloud.js";
-
-export async function onRequestGet(context: RequestContext) {
- const code = new URL(context.request.url).searchParams.get("code");
-
- if (!code) return jsonError("Missing code", 400);
-
- const dataTransferData = (await context.env.DATA.get(
- `datatransfer_${context.data.data_transfer_id}`,
- { type: "json" },
- )) as { [k: string]: any } | null;
-
- if (!dataTransferData)
- return jsonError("No transfer exists with that ID", 404);
-
- const exchangeReq = await fetch("https://apis.roblox.com/oauth/v1/token", {
- body: `code=${code}&grant_type=authorization_code`,
- headers: {
- authorization: `Basic ${
- btoa(context.env.ROBLOX_OAUTH_ID) +
- ":" +
- context.env.ROBLOX_OAUTH_SECRET
- }`,
- "content-type": "application/x-www-form-urlencoded",
- },
- method: "POST",
- });
-
- if (!exchangeReq.ok) return jsonError("Failed to redeem code", 500);
-
- const { id_token } = (await exchangeReq.json()) as { id_token: string };
-
- const { name, preferred_username, sub } = JSON.parse(
- atob(id_token.replaceAll("-", "+").replaceAll("_", "/")),
- );
-
- if (!preferred_username) return jsonError("Username missing", 500);
-
- const userObj = {
- displayName: name,
- id: parseInt(sub),
- name: preferred_username,
- };
-
- let redirectLocation = "/data-transfer/complete";
-
- if (dataTransferData.oldUser) {
- let banList;
-
- try {
- banList = (await getBanList(context)).value;
- } catch {
- return jsonError("Failed to create data transfer request", 500);
- }
-
- if (banList[userObj.id].BanType)
- return new Response(null, {
- headers: {
- location: redirectLocation,
- },
- status: 302,
- });
-
- dataTransferData.newUser = userObj;
-
- await fetch(
- `https://api.trello.com/1/cards?key=${context.env.TRELLO_API_KEY}&token=${context.env.TRELLO_API_TOKEN}`,
- {
- body: JSON.stringify({
- desc: `${dataTransferData.oldUser.name} -> ${userObj.name}\n${dataTransferData.oldUser.id} -> ${userObj.id}\nNO MODMAIL TICKET - WEBSITE FORM SUBMISSION`,
- idList: context.env.TRELLO_LIST_ID,
- name: `${dataTransferData.oldUser.name} | Data Transfer`,
- }),
- headers: {
- "content-type": "application/json",
- },
- method: "POST",
- },
- );
- } else {
- dataTransferData.oldUser = userObj;
- redirectLocation = "/data-transfer/destination-account";
- }
-
- return new Response(null, {
- headers: {
- location: redirectLocation,
- },
- status: 302,
- });
-}