Remove all api endpoints from frontend project
This commit is contained in:
34
src/app.d.ts
vendored
34
src/app.d.ts
vendored
@@ -1,21 +1,25 @@
|
|||||||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||||
|
|
||||||
|
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
interface Locals {
|
interface Locals {
|
||||||
user: {
|
// user: {
|
||||||
isLoggedIn: boolean;
|
// isLoggedIn: boolean;
|
||||||
email: string | null;
|
// email: string | null;
|
||||||
username: string | null;
|
// username: string | null;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
// interface PageData {}
|
// interface PageData {}
|
||||||
// interface PageState {}
|
// interface PageState {}
|
||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
email: string | null;
|
||||||
|
username: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Player {
|
export interface Player {
|
||||||
@@ -45,4 +49,4 @@ export interface GameSettings {
|
|||||||
export type WebSocketMessage = {
|
export type WebSocketMessage = {
|
||||||
type: string;
|
type: string;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,42 +1,43 @@
|
|||||||
import { redirect, type Handle, type HandleFetch } from '@sveltejs/kit';
|
// import { redirect, type Handle } from '@sveltejs/kit';
|
||||||
|
//
|
||||||
export const handle: Handle = async ({ event, resolve }) => {
|
// export const handle: Handle = async ({ event, resolve }) => {
|
||||||
const sessionId = event.cookies.get('session_id');
|
// const sessionId = event.cookies.get('session_id');
|
||||||
let user = {
|
// let user = {
|
||||||
isLoggedIn: false,
|
// isLoggedIn: false,
|
||||||
email: '',
|
// email: '',
|
||||||
username: ''
|
// username: ''
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
if (sessionId) {
|
// if (sessionId) {
|
||||||
const response = await fetch('http://localhost/api/user/me', {
|
// const response = await fetch('http://hitstar.xyz/api/user/me', {
|
||||||
headers: {
|
// headers: {
|
||||||
'Content-Type': 'application/json'
|
// 'Content-Type': 'application/json'
|
||||||
}
|
// },
|
||||||
});
|
// credentials: 'include'
|
||||||
console.log(response.status);
|
// });
|
||||||
console.log(JSON.stringify(response));
|
// console.log(response.status);
|
||||||
|
// console.log(await response.text());
|
||||||
if (response.status >= 200 && response.status < 300) {
|
//
|
||||||
const uBody = await response.json();
|
// if (response.status >= 200 && response.status < 300) {
|
||||||
user = {
|
// const uBody = await response.json();
|
||||||
isLoggedIn: true,
|
// user = {
|
||||||
email: uBody.email,
|
// isLoggedIn: true,
|
||||||
username: uBody.display_name || 'Unknown username'
|
// email: uBody.email,
|
||||||
};
|
// username: uBody.display_name || 'Unknown username'
|
||||||
}
|
// };
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
if (event.url.pathname.startsWith('/private') && !user.isLoggedIn) {
|
//
|
||||||
redirect(307, '/error');
|
// if (event.url.pathname.startsWith('/private') && !user.isLoggedIn) {
|
||||||
} else if (event.url.pathname.startsWith('/api') && !user.isLoggedIn) {
|
// redirect(307, '/error');
|
||||||
return new Response(null, { status: 401 });
|
// } else if (event.url.pathname.startsWith('/api') && !user.isLoggedIn) {
|
||||||
}
|
// return new Response(null, { status: 401 });
|
||||||
|
// }
|
||||||
event.locals.user = user;
|
//
|
||||||
const response = await resolve(event);
|
// event.locals.user = user;
|
||||||
return response;
|
// const response = await resolve(event);
|
||||||
};
|
// return response;
|
||||||
|
// };
|
||||||
|
|
||||||
// export const handleFetch: HandleFetch = async({request, fetch}) => {
|
// export const handleFetch: HandleFetch = async({request, fetch}) => {
|
||||||
// if (request.url
|
// if (request.url
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import type { PageServerLoad } from "./$types";
|
|
||||||
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ locals }) => {
|
|
||||||
return {
|
|
||||||
user: locals.user,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -7,8 +7,7 @@
|
|||||||
let loginError = $state('');
|
let loginError = $state('');
|
||||||
|
|
||||||
let { data }: PageProps = $props();
|
let { data }: PageProps = $props();
|
||||||
let user = $state(data.user);
|
let user = $state(data.user);
|
||||||
|
|
||||||
|
|
||||||
// Example login function (would connect to a real auth service)
|
// Example login function (would connect to a real auth service)
|
||||||
function handleLogin() {
|
function handleLogin() {
|
||||||
@@ -19,11 +18,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleLogout() {
|
function handleLogout() {
|
||||||
user.isLoggedIn = false;
|
user = null;
|
||||||
user.username = null;
|
|
||||||
user.email = null;
|
|
||||||
|
|
||||||
goto("/logout");
|
goto('/logout');
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLobby() {
|
function createLobby() {
|
||||||
@@ -43,7 +40,7 @@
|
|||||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between items-center">
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between items-center">
|
||||||
<h1 class="text-2xl font-bold text-indigo-600">Hitstar</h1>
|
<h1 class="text-2xl font-bold text-indigo-600">Hitstar</h1>
|
||||||
|
|
||||||
{#if user.isLoggedIn}
|
{#if user}
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="mr-4 text-gray-700">Welcome, {user.username}</span>
|
<span class="mr-4 text-gray-700">Welcome, {user.username}</span>
|
||||||
<button
|
<button
|
||||||
@@ -66,7 +63,7 @@
|
|||||||
<p class="text-xl text-gray-600">Place songs on a timeline in the correct order.</p>
|
<p class="text-xl text-gray-600">Place songs on a timeline in the correct order.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !user.isLoggedIn}
|
{#if !user}
|
||||||
<!-- Login Section -->
|
<!-- Login Section -->
|
||||||
<div class="bg-white rounded-lg shadow-md p-8 mb-6">
|
<div class="bg-white rounded-lg shadow-md p-8 mb-6">
|
||||||
<h3 class="text-xl font-semibold text-gray-800 mb-6">Sign In to Play</h3>
|
<h3 class="text-xl font-semibold text-gray-800 mb-6">Sign In to Play</h3>
|
||||||
|
|||||||
21
src/routes/+page.ts
Normal file
21
src/routes/+page.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import type { User } from '../app';
|
||||||
|
import type { PageLoad } from './$types';
|
||||||
|
|
||||||
|
export const load: PageLoad = async ({ fetch }) => {
|
||||||
|
const response = await fetch('http://hitstar.xyz/api/user/me', {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (response.status >= 200 && response.status < 300) {
|
||||||
|
const user: User = await response.json();
|
||||||
|
return {
|
||||||
|
user
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
console.log(await response.text());
|
||||||
|
return {
|
||||||
|
user: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { db } from '$lib/server/db';
|
|
||||||
import { lobbysTable, usersInLobby } from '$lib/server/db/schema';
|
|
||||||
import { json, type RequestHandler } from '@sveltejs/kit';
|
|
||||||
import { eq } from 'drizzle-orm';
|
|
||||||
|
|
||||||
|
|
||||||
export const POST: RequestHandler = async ({ request }) => {
|
|
||||||
const userReq = await request.json();
|
|
||||||
|
|
||||||
const userInLobby = (await db.$count(usersInLobby, eq(usersInLobby.userEmail, userReq.email))) > 0
|
|
||||||
if (userInLobby) {
|
|
||||||
const lobbys = await db.query.lobbysTable.findMany({
|
|
||||||
with: {
|
|
||||||
usersInLobby: true
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// This should be done with database queries
|
|
||||||
const lobby = lobbys.find((l) => l.usersInLobby.find((u) => u.userEmail == userReq.email))
|
|
||||||
|
|
||||||
return json(lobby, { status: 200 })
|
|
||||||
}
|
|
||||||
|
|
||||||
// const lobby = await db.transaction(async (tx) => {
|
|
||||||
const l: typeof lobbysTable.$inferInsert = {
|
|
||||||
hostEmail: userReq.email
|
|
||||||
};
|
|
||||||
const [lobby] = await db.insert(lobbysTable).values(l).onConflictDoNothing().returning();
|
|
||||||
const uLobby: typeof usersInLobby.$inferInsert = {
|
|
||||||
userEmail: userReq.email,
|
|
||||||
lobbyId: lobby.id
|
|
||||||
};
|
|
||||||
await db.insert(usersInLobby).values(uLobby);
|
|
||||||
// })
|
|
||||||
|
|
||||||
if (!lobby) {
|
|
||||||
return new Response(null, { status: 500 })
|
|
||||||
}
|
|
||||||
|
|
||||||
return json(lobby, { status: 201 })
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import { db } from "$lib/server/db";
|
|
||||||
import { usersTable } from "$lib/server/db/schema";
|
|
||||||
import { json, type RequestHandler } from "@sveltejs/kit";
|
|
||||||
|
|
||||||
export const POST: RequestHandler = async ({ request }) => {
|
|
||||||
const user = await request.json();
|
|
||||||
const u: typeof usersTable.$inferInsert = {
|
|
||||||
email: user.email,
|
|
||||||
username: user.username
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await db.insert(usersTable).values(u).onConflictDoNothing().returning();
|
|
||||||
|
|
||||||
if (result.length <= 0) {
|
|
||||||
return new Response(null, { status: 409 });
|
|
||||||
}
|
|
||||||
|
|
||||||
return json(result, { status: 201 })
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { db } from "$lib/server/db"
|
|
||||||
import { sessionsTable, usersTable } from "$lib/server/db/schema"
|
|
||||||
|
|
||||||
export async function POST() {
|
|
||||||
await db.delete(sessionsTable);
|
|
||||||
await db.delete(usersTable);
|
|
||||||
|
|
||||||
return new Response();
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import { redirect } from "@sveltejs/kit";
|
|
||||||
import type { PageServerLoad } from "./$types";
|
|
||||||
import { eq } from 'drizzle-orm';
|
|
||||||
import { db } from "$lib/server/db";
|
|
||||||
import { sessionsTable, states, usersTable } from "$lib/server/db/schema";
|
|
||||||
import { generateRandomString, getToken } from "$lib/server/auth/spotify";
|
|
||||||
import { getCurrentUserProfile } from "$lib/server/spotify/users";
|
|
||||||
import { env } from "$env/dynamic/public"
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ url, cookies }) => {
|
|
||||||
const code = url.searchParams.get('code');
|
|
||||||
const state = url.searchParams.get('state')
|
|
||||||
|
|
||||||
if (!state || !code) {
|
|
||||||
redirect(307, "/error")
|
|
||||||
}
|
|
||||||
|
|
||||||
const s = await db.select().from(states).where(eq(states.id, state)).limit(1);
|
|
||||||
|
|
||||||
if (s.length <= 0 || !s[0].codeVerifier) {
|
|
||||||
redirect(307, "/error")
|
|
||||||
}
|
|
||||||
const token = await getToken(code, s[0].codeVerifier)
|
|
||||||
|
|
||||||
// TODO: Check if deletion was fulfilled
|
|
||||||
await db.delete(states).where(eq(states.id, state));
|
|
||||||
|
|
||||||
const userResponse = await getCurrentUserProfile(token.access_token)
|
|
||||||
|
|
||||||
const isUser: boolean = (await db.$count(usersTable, eq(usersTable.email, userResponse.email))) === 1
|
|
||||||
|
|
||||||
if (!isUser) {
|
|
||||||
const user: typeof usersTable.$inferInsert = {
|
|
||||||
email: userResponse.email,
|
|
||||||
username: userResponse.display_name
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.insert(usersTable).values(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
const session: typeof sessionsTable.$inferInsert = {
|
|
||||||
id: generateRandomString(64),
|
|
||||||
accessToken: token.access_token,
|
|
||||||
refreshToken: token.refresh_token,
|
|
||||||
userEmail: userResponse.email,
|
|
||||||
// TODO: Session Timeouts MUST
|
|
||||||
}
|
|
||||||
|
|
||||||
const sessionResponse = await db.insert(sessionsTable).values(session);
|
|
||||||
|
|
||||||
cookies.set("session_id", session.id, { path: "/", secure: /^true$/i.test(env.PUBLIC_SECURE ?? "true") });
|
|
||||||
|
|
||||||
redirect(307, "/")
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { redirect } from "@sveltejs/kit";
|
|
||||||
import type { PageServerLoad } from "./$types";
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({locals, fetch}) => {
|
|
||||||
const response = await fetch("/api/createLobby", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
},
|
|
||||||
body: JSON.stringify(locals.user)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) redirect(307, "/error");
|
|
||||||
|
|
||||||
const lobby = await response.json();
|
|
||||||
|
|
||||||
redirect(307, `/lobby/${lobby.id}`);
|
|
||||||
};
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { env } from "$env/dynamic/public";
|
|
||||||
import { redirect } from "@sveltejs/kit";
|
|
||||||
import { generateRandomString, sha256, base64encode } from '$lib/server/auth/spotify';
|
|
||||||
import type { PageServerLoad } from "../$types";
|
|
||||||
import { db } from "$lib/server/db";
|
|
||||||
import { states } from "$lib/server/db/schema";
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async () => {
|
|
||||||
const scope = 'user-read-private user-read-email';
|
|
||||||
const authUrl = new URL("https://accounts.spotify.com/authorize");
|
|
||||||
|
|
||||||
const verifier = generateRandomString(64);
|
|
||||||
const state = generateRandomString(64);
|
|
||||||
|
|
||||||
const s: typeof states.$inferInsert = {
|
|
||||||
id: state,
|
|
||||||
codeVerifier: verifier
|
|
||||||
};
|
|
||||||
|
|
||||||
await db.insert(states).values(s);
|
|
||||||
|
|
||||||
const hashed = await sha256(verifier);
|
|
||||||
const codeChallenge = base64encode(hashed);
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
response_type: 'code',
|
|
||||||
client_id: env.PUBLIC_CLIENT_ID,
|
|
||||||
scope,
|
|
||||||
code_challenge_method: 'S256',
|
|
||||||
code_challenge: codeChallenge,
|
|
||||||
redirect_uri: env.PUBLIC_REDIRECT_URI,
|
|
||||||
state
|
|
||||||
}
|
|
||||||
|
|
||||||
authUrl.search = new URLSearchParams(params).toString();
|
|
||||||
redirect(307, authUrl);
|
|
||||||
};
|
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
import { db } from "$lib/server/db";
|
|
||||||
import { sessionsTable } from "$lib/server/db/schema";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import type { PageServerLoad } from "../$types";
|
|
||||||
import { redirect } from "@sveltejs/kit";
|
import { redirect } from "@sveltejs/kit";
|
||||||
|
import type { PageServerLoad } from "./$types";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ cookies }) => {
|
export const load: PageServerLoad = async ({ cookies }) => {
|
||||||
const sessionId = cookies.get('session_id');
|
const sessionId = cookies.get('session_id');
|
||||||
@@ -11,8 +8,6 @@ export const load: PageServerLoad = async ({ cookies }) => {
|
|||||||
redirect(307, "/error")
|
redirect(307, "/error")
|
||||||
}
|
}
|
||||||
|
|
||||||
db.delete(sessionsTable).where(eq(sessionsTable.id, sessionId))
|
cookies.delete('session_id', { path: "/", secure: false });
|
||||||
|
|
||||||
cookies.delete('session_id', { path: "/" });
|
|
||||||
redirect(307, "/")
|
redirect(307, "/")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<h1>
|
|
||||||
Hello :)
|
|
||||||
</h1>
|
|
||||||
Reference in New Issue
Block a user