mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-10-19 06:07:21 +02:00
fix: make dashboard UI consistent and compact on mobile
This commit is contained in:
1 parent
adc9dbd439
commit
282efdc16e
52 files changed
+2177
-712
No files matched your search
@@ -30,6 +30,7 @@ const UserSchema = new Schema({
|
||||
},
|
||||
],
|
||||
photo: String,
|
||||
projectNames: { type: Map, of: String },
|
||||
repositories: [
|
||||
{
|
||||
type: String,
|
||||
|
||||
@@ -25,6 +25,7 @@ export interface IUser {
|
||||
default: boolean;
|
||||
}[];
|
||||
photo?: string;
|
||||
projectNames?: Map<string, string>;
|
||||
|
||||
repositories?: number[];
|
||||
default?: {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { createHash } from "crypto";
|
||||
import AnonymousError from "../../core/AnonymousError";
|
||||
import User from "../../core/User";
|
||||
import UserModel from "../../core/model/users/users.model";
|
||||
|
||||
export function projectNameKey(type: string, id: string): string {
|
||||
return createHash("sha256").update(`${type}:${id}`).digest("hex");
|
||||
}
|
||||
|
||||
// Names belong to the user's dashboard, rather than the shared artifact.
|
||||
export async function saveProjectName(user: User, input: unknown): Promise<string> {
|
||||
const body = input as { type?: unknown; id?: unknown; name?: unknown } | null;
|
||||
if (!body || typeof body.type !== "string" || !["repo", "pr", "gist"].includes(body.type)
|
||||
|| typeof body.id !== "string" || !body.id || body.id.length > 250
|
||||
|| typeof body.name !== "string" || body.name.trim().length > 100
|
||||
|| Array.from(body.name).some(character => {
|
||||
const code = character.charCodeAt(0);
|
||||
return code < 32 || code === 127;
|
||||
})) {
|
||||
throw new AnonymousError("invalid_project_name", { httpStatus: 400 });
|
||||
}
|
||||
const type = String(body.type);
|
||||
const records = type === "repo" ? await user.getRepositories()
|
||||
: type === "pr" ? await user.getPullRequests() : await user.getGists();
|
||||
const field = type === "repo" ? "repoId" : type === "pr" ? "pullRequestId" : "gistId";
|
||||
if (!records.some(record => (record as unknown as Record<string, unknown>)[field] === body.id)) {
|
||||
throw new AnonymousError("not_authorized", { httpStatus: 403 });
|
||||
}
|
||||
const key = projectNameKey(type, body.id);
|
||||
const name = body.name.trim();
|
||||
const path = `projectNames.${key}`;
|
||||
await UserModel.updateOne({ _id: user.model._id }, name
|
||||
? { $set: { [path]: name } } : { $unset: { [path]: "" } });
|
||||
if (name) user.model.set(path, name);
|
||||
else user.model.projectNames?.delete(key);
|
||||
return name;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import FileModel from "../../core/model/files/files.model";
|
||||
import { isConnected } from "../database";
|
||||
import { octokit } from "../../core/GitHubUtils";
|
||||
import { createLogger, serializeError } from "../../core/logger";
|
||||
import { projectNameKey, saveProjectName } from "./project-names";
|
||||
|
||||
const logger = createLogger("user");
|
||||
|
||||
@@ -124,6 +125,15 @@ router.get("/quota", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/project-name", async (req, res) => {
|
||||
try {
|
||||
const user = await getUser(req);
|
||||
res.json({ name: await saveProjectName(user, req.body) });
|
||||
} catch (error) {
|
||||
handleError(error, res, req);
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/default", async (req, res) => {
|
||||
try {
|
||||
const user = await getUser(req);
|
||||
@@ -214,6 +224,7 @@ router.delete("/", async (req, res) => {
|
||||
externalIDs: "",
|
||||
photo: "",
|
||||
default: "",
|
||||
projectNames: "",
|
||||
},
|
||||
}
|
||||
).exec();
|
||||
@@ -239,6 +250,7 @@ router.get(
|
||||
(await user.getRepositories()).map((x) => {
|
||||
const json = x.toJSON() as Record<string, unknown>;
|
||||
json.role = x.owner.id === user.model.id ? "owner" : "coauthor";
|
||||
json.projectName = user.model.projectNames?.get(projectNameKey("repo", x.repoId));
|
||||
return json;
|
||||
})
|
||||
);
|
||||
@@ -254,7 +266,7 @@ router.get(
|
||||
const user = await getUser(req);
|
||||
res.json(
|
||||
(await user.getGists()).map((x) => {
|
||||
return x.toJSON();
|
||||
return { ...x.toJSON(), projectName: user.model.projectNames?.get(projectNameKey("gist", x.gistId)) };
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -269,7 +281,7 @@ router.get(
|
||||
const user = await getUser(req);
|
||||
res.json(
|
||||
(await user.getPullRequests()).map((x) => {
|
||||
return x.toJSON();
|
||||
return { ...x.toJSON(), projectName: user.model.projectNames?.get(projectNameKey("pr", x.pullRequestId)) };
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
Reference in new issue
Block a user