This repository has been archived on 2026-03-19. You can view files and clone it, but cannot push or open issues or pull requests.
Files
galvanic-corrosion/src/routes/account/account.ts
zombieb 9ce5431d9d
Some checks failed
Galvanic Corrosion Cross-Compile / build (push) Failing after 39s
various fixes
* Reverted shutdown mechanism
* Socket authentication fix for Cloudflare users
    - Cloudflare formats headers
* Steam auth verbose
* Upload artifacts to CDN and send Discord webhook link in #dev
2025-05-12 20:57:52 -04:00

153 lines
4.1 KiB
TypeScript

/* Galvanic Corrosion - Rec Room custom server for communities.
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
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 <https://www.gnu.org/licenses/>. */
import { APIUtils, NoBody } from "../../apiutils.ts";
import express from "express";
import UnifiedProfile, { Profile } from "../../data/profiles.ts";
import { z } from "zod";
import { AuthType } from "../../data/users.ts";
export const route = APIUtils.createRouter("/account");
const CreateAccountRequestBodySchema = z.object({
platform: z.string(),
platformId: z.string(),
deviceId: z.string()
});
const rateLimit = new APIUtils.RateLimiter();
route.router.post("/create",
rateLimit.middle(),
APIUtils.Authentication,
express.urlencoded({ extended: true }),
APIUtils.validateRequestBody(CreateAccountRequestBodySchema),
async (_rq, rs) => {
const newAcc = await Profile.init();
if (newAcc == null) {
rs.json({
success: false
});
return;
}
rs.locals.user.addAssociatedProfile(newAcc.getId());
rs.json({
success: true,
value: await newAcc.export(),
});
},
);
route.router.get("/bulk",
rateLimit.middle(),
async (rq: express.Request, rs: express.Response) => {
if (typeof rq.query.id == "object") {
const ids = Object.values(rq.query.id).filter((val) => typeof val == "string").map((val) => parseInt(val, 10)).filter((val) => !isNaN(val));
rs.json([...await Profile.getExportAccountsBulk(ids)]);
} else if (typeof rq.query.id == "string") {
const id = parseInt(rq.query.id);
if (isNaN(id)) {
rs.json(APIUtils.genericResponseFormat(true, "Query data error"));
return;
} else {
rs.json([await Profile.getExportAccount(id)].filter((val) => val !== null));
return;
}
} else {
rs.json([]);
return;
}
},
);
route.router.get("/me",
APIUtils.Authentication,
async (_rq, rs) => {
const exportAccount = await rs.locals.profile.export();
if (exportAccount == null) rs.sendStatus(500);
else rs.json(exportAccount);
},
);
interface DisplayNameUpdate {
displayName: string
}
const DisplayNameUpdateSchema = z.object({
displayName: z.string().max(24, "DisplayName too long!")
})
route.router.put("/me/displayname",
APIUtils.Authentication,
APIUtils.AuthenticationType(AuthType.Game),
express.urlencoded({ extended: true }),
APIUtils.validateRequestBody(DisplayNameUpdateSchema),
(rq: express.Request<NoBody, NoBody, DisplayNameUpdate>, rs: express.Response, nxt: express.NextFunction) => {
rs.locals.profile.setDisplayName(rq.body.displayName);
nxt();
},
APIUtils.RecNetResponse(true, "Updated DisplayName.")
);
interface BioFetchParams {
id?: string
}
route.router.get('/:id/bio',
APIUtils.Authentication,
async (rq: express.Request<BioFetchParams>, rs: express.Response) => {
const unparsedId = rq.params.id;
if (!unparsedId) {
rs.sendStatus(500);
return;
}
const parsedId = parseInt(unparsedId);
if (isNaN(parsedId)) {
rs.sendStatus(400);
return;
}
const player = UnifiedProfile.get(parsedId);
rs.json({
accountId: parsedId,
bio: await player.getBio(),
});
}
);