fix: make logging in not mandatory
All checks were successful
deploy to cloudflare pages / deploy (push) Successful in 32s
All checks were successful
deploy to cloudflare pages / deploy (push) Successful in 32s
This commit is contained in:
parent
d1a3772f6c
commit
67d2358a37
12 changed files with 99 additions and 24 deletions
|
@ -13,3 +13,8 @@ export interface User {
|
|||
name: string;
|
||||
avatarHash: string;
|
||||
}
|
||||
|
||||
export interface CookieData {
|
||||
state: string;
|
||||
next: string;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ let lazyTram: [GeoJSON.Feature, string][] | null = null;
|
|||
let lazyStops: GeoJSON.Feature[] | null = null;
|
||||
|
||||
export async function createGame(
|
||||
userId: string,
|
||||
userId: string | null,
|
||||
mode: string,
|
||||
stopsType: string,
|
||||
stops: GeoJSON.Feature[],
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import { redirect } from "@sveltejs/kit";
|
||||
import type { PageServerLoad } from "./$types";
|
||||
|
||||
export const load: PageServerLoad = async ({ locals }) => {
|
||||
if (locals.user === null) {
|
||||
redirect(302, "/login");
|
||||
} else {
|
||||
return { user: locals.user };
|
||||
}
|
||||
return { user: locals.user };
|
||||
};
|
||||
|
|
|
@ -6,9 +6,7 @@ export const GET: RequestHandler = async ({ url, platform, locals }) => {
|
|||
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||
if (db === null) error(500, "could not connect to d1");
|
||||
|
||||
const user = locals.user;
|
||||
if (user === null) error(401, "not logged in");
|
||||
|
||||
const userId = locals.user?.id ?? null;
|
||||
const options = parseOptions(url);
|
||||
|
||||
const crossingStops = await getMergedStops(options.stopsType);
|
||||
|
@ -18,7 +16,7 @@ export const GET: RequestHandler = async ({ url, platform, locals }) => {
|
|||
error(400, "could not select random stop");
|
||||
}
|
||||
|
||||
const gameData = await createGame(user.id, options.mode, options.stopsType, randomStops, db);
|
||||
const gameData = await createGame(userId, options.mode, options.stopsType, randomStops, db);
|
||||
|
||||
return Response.json(gameData);
|
||||
};
|
||||
|
|
16
src/routes/api/save/+server.ts
Normal file
16
src/routes/api/save/+server.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { error, redirect } from "@sveltejs/kit";
|
||||
import type { RequestHandler } from "./$types";
|
||||
|
||||
export const GET: RequestHandler = async ({ locals, platform, url }) => {
|
||||
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||
if (db === null) error(500, "could not connect to d1");
|
||||
|
||||
const gameId = url.searchParams.get("id") ?? null;
|
||||
if (gameId === null) error(400, "no game id specified");
|
||||
|
||||
if (locals.user === null) error(401);
|
||||
|
||||
await db.prepare("UPDATE game SET user_id = ? WHERE id = ?").bind(locals.user.id, gameId).run();
|
||||
|
||||
redirect(302, `/results?gameId=${gameId}`);
|
||||
};
|
|
@ -2,18 +2,20 @@ import { redirect } from "@sveltejs/kit";
|
|||
import { generateState } from "arctic";
|
||||
import { discord } from "$lib/auth/discord";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import type { CookieData } from "$lib/auth";
|
||||
|
||||
export const GET: RequestHandler = async ({ cookies, url }) => {
|
||||
const cookie: CookieData = { state: generateState(), next: url.searchParams.get("next") ?? "/" };
|
||||
|
||||
export const GET: RequestHandler = async ({ cookies }) => {
|
||||
const state = generateState();
|
||||
const scopes = ["identify"];
|
||||
const url = discord.createAuthorizationURL(state, scopes);
|
||||
const authUrl = discord.createAuthorizationURL(cookie.state, scopes);
|
||||
|
||||
cookies.set("discord_oauth_state", state, {
|
||||
cookies.set("discord_oauth_state", JSON.stringify(cookie), {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
maxAge: 60 * 10,
|
||||
sameSite: "lax",
|
||||
});
|
||||
|
||||
redirect(302, url);
|
||||
redirect(302, authUrl);
|
||||
};
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { error, redirect } from "@sveltejs/kit";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import { discord, type DiscordUser } from "$lib/auth/discord";
|
||||
import { OAuth2RequestError, type OAuth2Tokens } from "arctic";
|
||||
import { createSession, generateSessionToken } from "$lib/auth/session";
|
||||
import { setSessionTokenCookie } from "$lib/auth/cookie";
|
||||
import { destr } from "destr";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import type { CookieData } from "$lib/auth";
|
||||
|
||||
export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) => {
|
||||
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||
|
@ -11,13 +13,13 @@ export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) =>
|
|||
|
||||
const code = url.searchParams.get("code");
|
||||
const state = url.searchParams.get("state");
|
||||
const storedState = cookies.get("discord_oauth_state") ?? null;
|
||||
const cookie = destr<CookieData>(cookies.get("discord_oauth_state")) ?? null;
|
||||
|
||||
if (code === null || state === null || storedState === null) {
|
||||
if (code === null || state === null || cookie === null) {
|
||||
error(400, "missing things from oauth2 response");
|
||||
}
|
||||
|
||||
if (state !== storedState) {
|
||||
if (state !== cookie.state) {
|
||||
error(400, "state does not match");
|
||||
}
|
||||
|
||||
|
@ -49,5 +51,5 @@ export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) =>
|
|||
const session = await createSession(sessionToken, discordUser.id, db);
|
||||
setSessionTokenCookie(cookies, sessionToken, session.expiresAt);
|
||||
|
||||
redirect(302, "/");
|
||||
redirect(302, cookie.next);
|
||||
};
|
||||
|
|
|
@ -4,12 +4,13 @@ import { error } from "@sveltejs/kit";
|
|||
interface JoinedRoundScore {
|
||||
mode: string;
|
||||
total_score: number;
|
||||
name: string;
|
||||
points: number;
|
||||
distance: number;
|
||||
stop_name: string;
|
||||
}
|
||||
|
||||
export const load: PageServerLoad = async ({ url, platform }) => {
|
||||
export const load: PageServerLoad = async ({ locals, url, platform }) => {
|
||||
const db = platform?.env?.TCL_GUESSR_D1;
|
||||
if (!db) error(500, "could not connect to d1");
|
||||
|
||||
|
@ -18,10 +19,10 @@ export const load: PageServerLoad = async ({ url, platform }) => {
|
|||
|
||||
const { results } = await db
|
||||
.prepare(
|
||||
"SELECT game.mode, game.total_score, round.points, round.distance, round.stop_name FROM game INNER JOIN round ON round.game_id = game.id WHERE game.id = ?;",
|
||||
"SELECT game.mode, game.total_score, user.name, round.points, round.distance, round.stop_name FROM game INNER JOIN round ON round.game_id = game.id LEFT JOIN user ON user.id = game.user_id WHERE game.id = ?;",
|
||||
)
|
||||
.bind(gameId)
|
||||
.all<JoinedRoundScore>();
|
||||
|
||||
return { rounds: results, gameId };
|
||||
return { rounds: results, gameId, loggedIn: locals.user !== null };
|
||||
};
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
const totalScore = props.data.rounds[0].total_score;
|
||||
const mode = props.data.rounds[0].mode;
|
||||
const name = props.data.rounds[0].name;
|
||||
|
||||
const saveParams = new URLSearchParams({ next: `/api/save?id=${props.data.gameId}` });
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
|
@ -19,6 +22,14 @@
|
|||
|
||||
<span>mode: {mode}</span>
|
||||
|
||||
{#if name !== null}
|
||||
<span>joué par {name}</span>
|
||||
{:else if props.data.loggedIn}
|
||||
<span>joué par <i>un inconnu...</i></span>
|
||||
{:else}
|
||||
<span><a href="/login?{saveParams}">connectez vous</a> pour sauvegarder votre score!</span>
|
||||
{/if}
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
{#each props.data.rounds as round}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue