mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
tsconfig ES2020
This commit is contained in:
parent
0ba2b4c789
commit
7a613bd1da
4
app/features/calendar/calendar-utils.ts
Normal file
4
app/features/calendar/calendar-utils.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { userDiscordIdIsAged } from "~/utils/users";
|
||||
|
||||
export const canAddNewEvent = (user: { discordId: string }) =>
|
||||
userDiscordIdIsAged(user);
|
||||
|
|
@ -34,7 +34,7 @@ import type {
|
|||
import { useIsMounted } from "~/hooks/useIsMounted";
|
||||
import { useTranslation } from "~/hooks/useTranslation";
|
||||
import { useUser } from "~/features/auth/core";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import { i18next } from "~/modules/i18n";
|
||||
import { MapPool } from "~/features/map-list-generator/core/map-pool";
|
||||
import { canEditCalendarEvent, canEnableTOTools } from "~/permissions";
|
||||
|
|
@ -71,6 +71,7 @@ import type { RankedModeShort } from "~/modules/in-game-lists";
|
|||
import { rankedModesShort } from "~/modules/in-game-lists/modes";
|
||||
import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import { canAddNewEvent } from "../calendar-utils";
|
||||
|
||||
const MIN_DATE = new Date(Date.UTC(2015, 4, 28));
|
||||
|
||||
|
|
@ -136,12 +137,14 @@ const newCalendarEventActionSchema = z.object({
|
|||
});
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser(request);
|
||||
const data = await parseRequestFormData({
|
||||
request,
|
||||
schema: newCalendarEventActionSchema,
|
||||
});
|
||||
|
||||
validate(canAddNewEvent(user), "Not authorized", 401);
|
||||
|
||||
const commonArgs = {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
|
|
@ -207,9 +210,11 @@ export const handle: SendouRouteHandle = {
|
|||
|
||||
export const loader = async ({ request }: LoaderArgs) => {
|
||||
const t = await i18next.getFixedT(request);
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser(request);
|
||||
const url = new URL(request.url);
|
||||
|
||||
validate(canAddNewEvent(user), "Not authorized", 401);
|
||||
|
||||
const eventId = Number(url.searchParams.get("eventId"));
|
||||
const eventToEdit = Number.isNaN(eventId)
|
||||
? undefined
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import { Tags } from "../components/Tags";
|
|||
import { Divider } from "~/components/Divider";
|
||||
import { UsersIcon } from "~/components/icons/Users";
|
||||
import * as CalendarRepository from "../CalendarRepository.server";
|
||||
import { canAddNewEvent } from "../calendar-utils";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
|
|
@ -176,7 +177,7 @@ export default function CalendarPage() {
|
|||
<WeekLinks />
|
||||
<EventsToReport />
|
||||
<div className="stack md">
|
||||
{user && (
|
||||
{user && canAddNewEvent(user) && (
|
||||
<LinkButton to="new" className="calendar__add-new-button" size="tiny">
|
||||
{t("addNew")}
|
||||
</LinkButton>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { suite } from "uvu";
|
||||
import * as assert from "uvu/assert";
|
||||
import { queryToUserIdentifier } from "./users";
|
||||
import { queryToUserIdentifier, userDiscordIdIsAged } from "./users";
|
||||
import MockDate from "mockdate";
|
||||
|
||||
const QueryToUserIdentifier = suite("queryToUserIdentifier()");
|
||||
const UserDiscordIdIsAged = suite("userDiscordIdIsAged()");
|
||||
|
||||
QueryToUserIdentifier("returns null if no match", () => {
|
||||
assert.equal(queryToUserIdentifier("foo"), null);
|
||||
|
|
@ -41,4 +43,32 @@ QueryToUserIdentifier("gets id", () => {
|
|||
});
|
||||
});
|
||||
|
||||
UserDiscordIdIsAged.before.each(() => {
|
||||
MockDate.set(new Date("2023-11-25T00:00:00.000Z"));
|
||||
});
|
||||
|
||||
UserDiscordIdIsAged.after.each(() => {
|
||||
MockDate.reset();
|
||||
});
|
||||
|
||||
UserDiscordIdIsAged("returns false if discord id is not aged", () => {
|
||||
assert.equal(
|
||||
userDiscordIdIsAged({ discordId: "1177730652641181871" }),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
UserDiscordIdIsAged("returns true if discord id is aged", () => {
|
||||
assert.equal(userDiscordIdIsAged({ discordId: "79237403620945920" }), true);
|
||||
});
|
||||
|
||||
UserDiscordIdIsAged("throws error if discord id missing", () => {
|
||||
assert.throws(() => userDiscordIdIsAged({ discordId: "" }));
|
||||
});
|
||||
|
||||
UserDiscordIdIsAged("throws error if discord id too short", () => {
|
||||
assert.throws(() => userDiscordIdIsAged({ discordId: "1234" }));
|
||||
});
|
||||
|
||||
QueryToUserIdentifier.run();
|
||||
UserDiscordIdIsAged.run();
|
||||
|
|
|
|||
|
|
@ -38,3 +38,30 @@ export function queryToUserIdentifier(
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
// snowflake logic from https://github.dev/vegeta897/snow-stamp/blob/main/src/util.js
|
||||
const DISCORD_EPOCH = 1420070400000;
|
||||
|
||||
// Converts a snowflake ID string into a JS Date object using the provided epoch (in ms), or Discord's epoch if not provided
|
||||
function convertSnowflakeToDate(snowflake: string) {
|
||||
// Convert snowflake to BigInt to extract timestamp bits
|
||||
// https://discord.com/developers/docs/reference#snowflakes
|
||||
const milliseconds = BigInt(snowflake) >> 22n;
|
||||
return new Date(Number(milliseconds) + DISCORD_EPOCH);
|
||||
}
|
||||
|
||||
const AGED_CRITERIA = 1000 * 60 * 60 * 24 * 30 * 3; // 3 months
|
||||
export function userDiscordIdIsAged(user: { discordId: string }) {
|
||||
// types should catch this but since this is a permission related
|
||||
// code playing it safe
|
||||
if (!user.discordId) {
|
||||
throw new Error("No discord id");
|
||||
}
|
||||
if (user.discordId.length < DISCORD_ID_MIN_LENGTH) {
|
||||
throw new Error("Not a valid discord id");
|
||||
}
|
||||
|
||||
const timestamp = convertSnowflakeToDate(user.discordId).getTime();
|
||||
|
||||
return Date.now() - timestamp > AGED_CRITERIA;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"jsx": "react-jsx",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"target": "ES2019",
|
||||
"target": "ES2020",
|
||||
"strict": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user