mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-24 23:19:39 -05:00
Improve getting started with project experience
This commit is contained in:
parent
027adf3bb0
commit
67c8b2c449
|
|
@ -1,10 +1,9 @@
|
|||
PORT=5800
|
||||
BASE_URL=http://localhost:5800
|
||||
DB_PATH=db.sqlite3
|
||||
|
||||
// auth
|
||||
LOHI_TOKEN=salmon
|
||||
SESSION_SECRET=secret
|
||||
DISCORD_CLIENT_ID=
|
||||
DISCORD_CLIENT_SECRET=
|
||||
|
||||
LOHI_TOKEN=salmon
|
||||
// needed for testing real auth only - values from https://discord.com/developers
|
||||
DISCORD_CLIENT_ID=
|
||||
DISCORD_CLIENT_SECRET=
|
||||
16
README.md
16
README.md
|
|
@ -2,21 +2,32 @@ Note: This is the WIP Splatoon 3 version of the site. To see the current live ve
|
|||
|
||||
## Running locally
|
||||
|
||||
### sendou.ink
|
||||
|
||||
Prerequisites: [nvm](https://github.com/nvm-sh/nvm)
|
||||
|
||||
There is a sequence of commands you need to run:
|
||||
|
||||
1. `nvm use` to switch to the correct Node version.
|
||||
2. `npm i` to install the dependencies.
|
||||
3. Make a copy of `.env.example` that's called `.env` and fill it with values.
|
||||
3. Make a copy of `.env.example` that's called `.env`. See below for note about environment variables.
|
||||
4. `npm run migrate` to set up the database tables.
|
||||
5. `npm run dev` to run both the server and frontend.
|
||||
5. `npm run seed` to fill database with test data.
|
||||
6. `npm run dev` to run the project in development mode.
|
||||
|
||||
And if you want to run the E2E tests:
|
||||
|
||||
6. Make a copy of the `db.sqlite3` file created by migration and name it `db-cypress.sqlite3`.
|
||||
7. `npm run dev:cypress` and `npm run cy:open` can be used to run the E2E tests.
|
||||
|
||||
#### Environment variables
|
||||
|
||||
You don't need to fill the missing values from `.env.example` to get started. Instead of using real auth via Discord you can "impersonate" the admin (=Sendou#0043) or any other use in the /admin page once the project has started up. `LOHI_TOKEN` is only needed for bot + sendou.ink interoperability.
|
||||
|
||||
### Lohi
|
||||
|
||||
TODO: instructions on how to develop Lohi locally
|
||||
|
||||
## Project structure
|
||||
|
||||
```
|
||||
|
|
@ -31,6 +42,7 @@ sendou.ink/
|
|||
│ ├── utils/ -- Random helper functions used in many places
|
||||
│ └── permissions.ts / -- What actions are allowed. Separated by frontend and backend as frontend has constraints based on what user sees.
|
||||
├── cypress/ -- see: https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests#Folder-structure
|
||||
├── discord-bot/ -- Lohi Discord bot that works together with sendou.ink
|
||||
├── migrations/ -- Database migrations
|
||||
├── public/ -- Images, built assets etc. static files to be served as is
|
||||
└── scripts/ -- Stand-alone scripts to be run outside of the app
|
||||
|
|
|
|||
|
|
@ -41,20 +41,15 @@ export class DiscordStrategy extends OAuth2Strategy<
|
|||
scope: string;
|
||||
|
||||
constructor() {
|
||||
invariant(process.env["DISCORD_CLIENT_ID"]);
|
||||
invariant(process.env["DISCORD_CLIENT_SECRET"]);
|
||||
invariant(process.env["BASE_URL"]);
|
||||
const envVars = authEnvVars();
|
||||
|
||||
super(
|
||||
{
|
||||
authorizationURL: "https://discord.com/api/oauth2/authorize",
|
||||
tokenURL: "https://discord.com/api/oauth2/token",
|
||||
clientID: process.env["DISCORD_CLIENT_ID"],
|
||||
clientSecret: process.env["DISCORD_CLIENT_SECRET"],
|
||||
callbackURL: new URL(
|
||||
"/auth/callback",
|
||||
process.env["BASE_URL"]
|
||||
).toString(),
|
||||
clientID: envVars.DISCORD_CLIENT_ID,
|
||||
clientSecret: envVars.DISCORD_CLIENT_SECRET,
|
||||
callbackURL: new URL("/auth/callback", envVars.BASE_URL).toString(),
|
||||
},
|
||||
async ({ accessToken }) => {
|
||||
const authHeader = ["Authorization", `Bearer ${accessToken}`];
|
||||
|
|
@ -133,3 +128,24 @@ export class DiscordStrategy extends OAuth2Strategy<
|
|||
return new URLSearchParams(urlSearchParams);
|
||||
}
|
||||
}
|
||||
|
||||
function authEnvVars() {
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
invariant(process.env["DISCORD_CLIENT_ID"]);
|
||||
invariant(process.env["DISCORD_CLIENT_SECRET"]);
|
||||
invariant(process.env["BASE_URL"]);
|
||||
|
||||
return {
|
||||
DISCORD_CLIENT_ID: process.env["DISCORD_CLIENT_ID"],
|
||||
DISCORD_CLIENT_SECRET: process.env["DISCORD_CLIENT_SECRET"],
|
||||
BASE_URL: process.env["BASE_URL"],
|
||||
};
|
||||
}
|
||||
|
||||
// allow running the project in development without setting auth env vars
|
||||
return {
|
||||
DISCORD_CLIENT_ID: process.env["DISCORD_CLIENT_ID"] ?? "",
|
||||
DISCORD_CLIENT_SECRET: process.env["DISCORD_CLIENT_SECRET"] ?? "",
|
||||
BASE_URL: process.env["BASE_URL"] ?? "",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { Catcher } from "~/components/Catcher";
|
|||
import { UserCombobox } from "~/components/Combobox";
|
||||
import { Main } from "~/components/Main";
|
||||
import { requireUser } from "~/modules/auth";
|
||||
import { isImpersonating } from "~/modules/auth/user.server";
|
||||
import { getUser, isImpersonating } from "~/modules/auth/user.server";
|
||||
import { canPerformAdminActions } from "~/permissions";
|
||||
import { makeTitle, parseRequestFormData, validate } from "~/utils/remix";
|
||||
import { impersonateUrl, STOP_IMPERSONATING_URL } from "~/utils/urls";
|
||||
|
|
@ -52,7 +52,7 @@ interface AdminPageLoaderData {
|
|||
}
|
||||
|
||||
export const loader: LoaderFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await getUser(request);
|
||||
|
||||
if (!canPerformAdminActions(user)) {
|
||||
return redirect("/");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user