Access command initial

This commit is contained in:
Kalle
2022-06-18 22:33:14 +03:00
parent f9d3265e88
commit 1c814317c0
10 changed files with 161 additions and 9 deletions

View File

@@ -5,4 +5,6 @@ DB_PATH=db.sqlite3
// auth
SESSION_SECRET=secret
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_CLIENT_SECRET=
LOHI_TOKEN=salmon

View File

@@ -11,3 +11,5 @@ export const PLUS_UPVOTE = 1;
export const PLUS_DOWNVOTE = -1;
export const ADMIN_DISCORD_ID = "79237403620945920";
export const LOHI_TOKEN_HEADER_NAME = "Lohi-Token";

View File

@@ -83,3 +83,19 @@ export function findAll() {
"id" | "discordId" | "discordName" | "discordDiscriminator" | "plusTier"
>[];
}
const findAllPlusMembersStm = sql.prepare(`
SELECT "User"."discordId", "PlusTier"."tier" as "plusTier"
FROM "User"
LEFT JOIN "PlusTier" ON "PlusTier"."userId" = "User".id
WHERE "PlusTier"."tier" IS NOT NULL
`);
export type FindAllPlusMembers = Pick<
UserWithPlusTier,
"discordId" | "plusTier"
>[];
export function findAllPlusMembers() {
return findAllPlusMembersStm.all() as FindAllPlusMembers;
}

View File

@@ -2,7 +2,8 @@ import type * as plusSuggestions from "~/db/models/plusSuggestions.server";
import { monthsVotingRange } from "./modules/plus-server";
import type { PlusSuggestion, User, UserWithPlusTier } from "./db/types";
import { allTruthy } from "./utils/arrays";
import { ADMIN_DISCORD_ID } from "./constants";
import { ADMIN_DISCORD_ID, LOHI_TOKEN_HEADER_NAME } from "./constants";
import invariant from "tiny-invariant";
// TODO: 1) move "root checkers" to one file and utils to one file 2) make utils const for more terseness
@@ -206,3 +207,10 @@ export function canPerformAdminActions(user?: Pick<User, "discordId">) {
if (!user) return false;
return user.discordId === ADMIN_DISCORD_ID;
}
invariant(process.env["LOHI_TOKEN"], "LOHI_TOKEN is required");
export function canAccessLohiEndpoint(request: Request) {
return (
request.headers.get(LOHI_TOKEN_HEADER_NAME) === process.env["LOHI_TOKEN"]
);
}

17
app/routes/plus/list.ts Normal file
View File

@@ -0,0 +1,17 @@
import { json } from "@remix-run/node";
import type { LoaderFunction } from "@remix-run/node";
import { db } from "~/db";
import { canAccessLohiEndpoint } from "~/permissions";
import type { FindAllPlusMembers } from "~/db/models/users.server";
export interface PlusListLoaderData {
users: FindAllPlusMembers;
}
export const loader: LoaderFunction = ({ request }) => {
if (!canAccessLohiEndpoint(request)) {
throw new Response(null, { status: 403 });
}
return json<PlusListLoaderData>({ users: db.users.findAllPlusMembers() });
};

View File

@@ -1,3 +1,5 @@
BOT_TOKEN=
TEST_GUILD_ID=
BOT_ID=
BOT_ID=
SENDOU_INK_URL=http://localhost:5800
LOHI_TOKEN=salmon

View File

@@ -0,0 +1,45 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import invariant from "tiny-invariant";
import { LOHI_TOKEN_HEADER_NAME } from "~/constants";
import type { PlusListLoaderData } from "~/routes/plus/list";
import ids from "../ids";
import type { BotCommand } from "../types";
const COMMAND_NAME = "access";
export const accessCommand: BotCommand = {
guilds: [ids.guilds.plusServer],
name: COMMAND_NAME,
builder: new SlashCommandBuilder()
.setName(COMMAND_NAME)
.setDescription(
"Get the corresponding Plus Server membership role if you have access"
),
execute: async ({ interaction }) => {
const { users } = await usersWithAccess();
if (!users.some((u) => u.discordId === interaction.user.id)) {
return interaction.reply("You currently don't have access");
}
// TODO: logic to change roles here
return interaction.reply("ok");
},
};
async function usersWithAccess(): Promise<PlusListLoaderData> {
invariant(process.env["SENDOU_INK_URL"], "SENDOU_INK_URL is not set");
invariant(process.env["LOHI_TOKEN"], "LOHI_TOKEN is not set");
const response = await fetch(`${process.env["SENDOU_INK_URL"]}/plus/list`, {
headers: [[LOHI_TOKEN_HEADER_NAME, process.env["LOHI_TOKEN"]]],
});
if (!response.ok) {
throw new Error(
`Failed to fetch users. Response status was ${response.status}`
);
}
return response.json();
}

View File

@@ -1,8 +1,9 @@
import { questionCommand } from "./q";
import { lfgRoleCommand } from "./lfg";
import { accessCommand } from "./access";
import type { BotCommand } from "discord-bot/types";
export const commands = [questionCommand, lfgRoleCommand];
export const commands = [questionCommand, lfgRoleCommand, accessCommand];
export const commandsMap = Object.fromEntries(commands.map((c) => [c.name, c]));

View File

@@ -1,13 +1,11 @@
{
"name": "discord-bot",
"name": "lohi",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "discord-bot",
"version": "1.0.0",
"license": "ISC",
"name": "lohi",
"dependencies": {
"@discordjs/builders": "^0.15.0",
"@discordjs/rest": "^0.5.0",
@@ -16,6 +14,7 @@
"dotenv": "^16.0.1",
"tiny-invariant": "^1.2.0",
"ts-node": "^10.8.1",
"tsconfig-paths": "^4.0.0",
"typescript": "^4.7.3"
}
},
@@ -328,6 +327,17 @@
"node": ">= 6"
}
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
@@ -352,6 +362,11 @@
"node": ">= 0.6"
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -371,6 +386,14 @@
}
}
},
"node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"engines": {
"node": ">=4"
}
},
"node_modules/tiny-invariant": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz",
@@ -428,6 +451,16 @@
}
}
},
"node_modules/tsconfig-paths": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.0.0.tgz",
"integrity": "sha512-SLBg2GBKlR6bVtMgJJlud/o3waplKtL7skmLkExomIiaAtLGtVsoXIqP3SYdjbcH9lq/KVv7pMZeCBpLYOit6Q==",
"dependencies": {
"json5": "^2.2.1",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
},
"node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
@@ -752,6 +785,11 @@
"mime-types": "^2.1.12"
}
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
@@ -770,6 +808,11 @@
"mime-db": "1.52.0"
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -778,6 +821,11 @@
"whatwg-url": "^5.0.0"
}
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="
},
"tiny-invariant": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz",
@@ -813,6 +861,16 @@
"yn": "3.1.1"
}
},
"tsconfig-paths": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.0.0.tgz",
"integrity": "sha512-SLBg2GBKlR6bVtMgJJlud/o3waplKtL7skmLkExomIiaAtLGtVsoXIqP3SYdjbcH9lq/KVv7pMZeCBpLYOit6Q==",
"requires": {
"json5": "^2.2.1",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
},
"tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",

View File

@@ -1,7 +1,7 @@
{
"name": "lohi",
"scripts": {
"dev": "ts-node index.ts",
"dev": "node --experimental-fetch --require ts-node/register --require tsconfig-paths/register index.ts",
"commands": "ts-node deploy-commands.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
@@ -13,6 +13,7 @@
"dotenv": "^16.0.1",
"tiny-invariant": "^1.2.0",
"ts-node": "^10.8.1",
"tsconfig-paths": "^4.0.0",
"typescript": "^4.7.3"
}
}