diff --git a/api/src/hooks.server.ts b/api/src/hooks.server.ts
index 0fc1d13..1855089 100644
--- a/api/src/hooks.server.ts
+++ b/api/src/hooks.server.ts
@@ -1,8 +1,7 @@
-import { dev } from '$app/environment';
import type { Handle } from '@sveltejs/kit';
-import { APP_DOMAIN, DASHBOARD_DOMAIN } from '../../shared/config';
+import { APP_BASE, DASHBOARD_BASE } from '$lib/server/config';
-const domainsWithAccessToAPI = [APP_DOMAIN, DASHBOARD_DOMAIN, 'https://checkout.stripe.com'];
+const domainsWithAccessToAPI = [APP_BASE, DASHBOARD_BASE, 'https://checkout.stripe.com'];
const publicEndpoints = ['/', '/checkout/success'];
const appendHeaders = (response: Response, origin: string | null) => {
@@ -21,7 +20,7 @@ export const handle: Handle = async ({ resolve, event }) => {
return response;
}
- if ((origin === null || !domainsWithAccessToAPI.includes(origin)) && !dev) {
+ if (!origin || !domainsWithAccessToAPI.includes(origin)) {
console.error(`Unauthorized access attempt from origin: ${origin}`);
return new Response('Unauthorised', { status: 401 });
}
diff --git a/api/src/lib/server/config.ts b/api/src/lib/server/config.ts
new file mode 100644
index 0000000..2a9e63d
--- /dev/null
+++ b/api/src/lib/server/config.ts
@@ -0,0 +1,10 @@
+import { dev } from '$app/environment';
+import {
+ APP_DOMAIN,
+ APP_LOCAL_PORT,
+ DASHBOARD_DOMAIN,
+ DASHBOARD_LOCAL_PORT
+} from '../../../../shared/config';
+
+export const APP_BASE = dev ? `http://localhost:${APP_LOCAL_PORT}` : APP_DOMAIN;
+export const DASHBOARD_BASE = dev ? `http://localhost:${DASHBOARD_LOCAL_PORT}` : DASHBOARD_DOMAIN;
diff --git a/app/src/lib/global/config.ts b/app/src/lib/global/config.ts
index 12da20b..5a4b670 100644
--- a/app/src/lib/global/config.ts
+++ b/app/src/lib/global/config.ts
@@ -1,5 +1,5 @@
import { dev } from '$app/environment';
-import { API_DOMAIN, API_LOCAL_PORT } from '../../../../shared/config';
+import { API_DOMAIN, API_LOCAL_PORT, APP_DOMAIN, APP_LOCAL_PORT } from '../../../../shared/config';
export const PUBLIC_SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL;
export const PUBLIC_SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_ANON_KEY;
@@ -7,3 +7,9 @@ export const PUBLIC_SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_ANON_KEY;
export const PUBLIC_PATH_ROOTS = ['/login', '/auth', '/about', '/contact', '/privacy', '/terms'];
export const API_BASE = dev ? `http://localhost:${API_LOCAL_PORT}` : API_DOMAIN;
+const APP_BASE = dev ? `http://localhost:${APP_LOCAL_PORT}` : APP_DOMAIN;
+
+export const REQUEST_HEADER_BOILERPLATE = {
+ 'Content-Type': 'application/json',
+ origin: APP_BASE
+};
diff --git a/app/src/lib/remote-functions/collections.remote.ts b/app/src/lib/remote-functions/collections.remote.ts
index c67234d..2cc4f30 100644
--- a/app/src/lib/remote-functions/collections.remote.ts
+++ b/app/src/lib/remote-functions/collections.remote.ts
@@ -1,8 +1,7 @@
-import { form, query } from '$app/server';
-import { API_BASE } from '$lib/global/config';
+import { form } from '$app/server';
+import { API_BASE, REQUEST_HEADER_BOILERPLATE } from '$lib/global/config';
import * as z from 'zod';
import { requireAuth } from './auth-check';
-import { redirect } from '@sveltejs/kit';
const MakeCollectionForm = z.object({
name: z.string().min(3).max(100),
@@ -23,9 +22,7 @@ export const makeCollection = form(MakeCollectionForm, async ({ name, descriptio
const userId = requireAuth().id;
await fetch(`${API_BASE}/collections`, {
method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ userId, name, description })
});
});
@@ -34,9 +31,7 @@ export const deleteCollection = form(DeleteCollectionForm, async ({ collectionId
const userId = requireAuth().id;
await fetch(`${API_BASE}/collections/${collectionId}`, {
method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ userId })
});
});
@@ -46,17 +41,8 @@ export const addOrRemoveReleaseFromCollection = form(
async ({ collectionId, releaseId, addOrRemove }) => {
await fetch(`${API_BASE}/collections/${collectionId}`, {
method: 'PATCH',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ releaseId, addOrRemove })
});
}
);
-
-export const getCollection = query(z.string(), async (collectionId: string) => {
- const response = await fetch(`${API_BASE}/collections/${collectionId}`);
- if (!response.ok) throw redirect(302, '/me/collections');
- const collection = await response.json();
- return collection;
-});
diff --git a/app/src/lib/remote-functions/mixtapes.remote.ts b/app/src/lib/remote-functions/mixtapes.remote.ts
index e693610..6749730 100644
--- a/app/src/lib/remote-functions/mixtapes.remote.ts
+++ b/app/src/lib/remote-functions/mixtapes.remote.ts
@@ -1,9 +1,7 @@
-import { form, query } from '$app/server';
-import { API_BASE } from '$lib/global/config';
+import { form } from '$app/server';
+import { API_BASE, REQUEST_HEADER_BOILERPLATE } from '$lib/global/config';
import * as z from 'zod';
import { requireAuth } from './auth-check';
-import type { MixtapeHydrated } from '../../../../shared/types/hydrated';
-import { redirect } from '@sveltejs/kit';
const MakeMixtapeForm = z.object({
name: z.string().min(3).max(100),
@@ -15,20 +13,11 @@ const AddTrackToMixtape = z.object({
trackId: z.string()
});
-export const getMixtape = query(z.string(), async (mixtapeId: string) => {
- const response = await fetch(`${API_BASE}/mixtapes/${mixtapeId}`);
- if (!response.ok) throw redirect(302, '/me/mixtapes');
- const mixtape: MixtapeHydrated = await response.json();
- return mixtape;
-});
-
export const makeMixtape = form(MakeMixtapeForm, async ({ name, description }) => {
const userId = requireAuth().id;
await fetch(`${API_BASE}/mixtapes`, {
method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ userId, name, description })
});
});
@@ -37,9 +26,7 @@ export const deleteMixtape = form(z.object({ mixtapeId: z.string() }), async ({
const userId = requireAuth().id;
await fetch(`${API_BASE}/mixtapes/${mixtapeId}`, {
method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ userId })
});
});
@@ -47,9 +34,7 @@ export const deleteMixtape = form(z.object({ mixtapeId: z.string() }), async ({
export const addTrackToMixtape = form(AddTrackToMixtape, async ({ mixtapeId, trackId }) => {
await fetch(`${API_BASE}/mixtapes/${mixtapeId}`, {
method: 'PATCH',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ trackId })
});
});
diff --git a/app/src/lib/remote-functions/releases.remote.ts b/app/src/lib/remote-functions/releases.remote.ts
index 9ffe60c..dfaa927 100644
--- a/app/src/lib/remote-functions/releases.remote.ts
+++ b/app/src/lib/remote-functions/releases.remote.ts
@@ -1,10 +1,13 @@
import { query } from '$app/server';
-import { API_BASE } from '$lib/global/config';
+import { API_BASE, REQUEST_HEADER_BOILERPLATE } from '$lib/global/config';
import * as z from 'zod';
import type { ReleaseHydrated } from '../../../../shared/types/hydrated';
export const getHydratedRelease = query(z.string(), async (releaseId: string) => {
- const response = await fetch(`${API_BASE}/releases/${releaseId}`);
+ const response = await fetch(`${API_BASE}/releases/${releaseId}`, {
+ method: 'GET',
+ headers: REQUEST_HEADER_BOILERPLATE
+ });
if (!response.ok) throw new Error('Failed to fetch release');
const release: ReleaseHydrated = await response.json();
return release;
diff --git a/app/src/lib/remote-functions/user.remote.ts b/app/src/lib/remote-functions/user.remote.ts
index 8e77024..d93e20c 100644
--- a/app/src/lib/remote-functions/user.remote.ts
+++ b/app/src/lib/remote-functions/user.remote.ts
@@ -1,5 +1,5 @@
import { form } from '$app/server';
-import { API_BASE } from '$lib/global/config';
+import { API_BASE, REQUEST_HEADER_BOILERPLATE } from '$lib/global/config';
import * as z from 'zod';
import { requireAuth } from './auth-check';
@@ -20,9 +20,7 @@ export const toggleFollowedArtist = form(
await fetch(`${API_BASE}/users/${userId}/following`, {
method: addOrRemove === 'remove' ? 'DELETE' : 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ artistId: artistID })
});
}
@@ -33,9 +31,7 @@ export const toggleLikedTrack = form(ToggleLikedTrackForm, async ({ trackId, add
await fetch(`${API_BASE}/users/${userId}/likes`, {
method: addOrRemove === 'remove' ? 'DELETE' : 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
+ headers: REQUEST_HEADER_BOILERPLATE,
body: JSON.stringify({ trackId })
});
});
diff --git a/app/src/routes/me/collections/[slug]/+page.svelte b/app/src/routes/me/collections/[slug]/+page.svelte
index 93b415e..b034236 100644
--- a/app/src/routes/me/collections/[slug]/+page.svelte
+++ b/app/src/routes/me/collections/[slug]/+page.svelte
@@ -1,12 +1,25 @@
diff --git a/app/src/routes/me/collections/[slug]/+page.ts b/app/src/routes/me/collections/[slug]/+page.ts
new file mode 100644
index 0000000..63eb4c9
--- /dev/null
+++ b/app/src/routes/me/collections/[slug]/+page.ts
@@ -0,0 +1,16 @@
+import { API_BASE } from '$lib/global/config';
+import type { CollectionHydrated } from '../../../../../../shared/types/hydrated';
+
+export const load = async ({ fetch, params }) => {
+ const collection: CollectionHydrated = await fetch(`${API_BASE}/collections/${params.slug}`).then(
+ (res) => res.json()
+ );
+ if (!collection)
+ return {
+ status: 404,
+ error: new Error('Not Found')
+ };
+ return {
+ collection
+ };
+};
diff --git a/app/src/routes/me/mixtapes/[slug]/+page.svelte b/app/src/routes/me/mixtapes/[slug]/+page.svelte
index 3bcfd48..bfde1c5 100644
--- a/app/src/routes/me/mixtapes/[slug]/+page.svelte
+++ b/app/src/routes/me/mixtapes/[slug]/+page.svelte
@@ -1,12 +1,29 @@
diff --git a/app/src/routes/me/mixtapes/[slug]/+page.ts b/app/src/routes/me/mixtapes/[slug]/+page.ts
new file mode 100644
index 0000000..88bbfe8
--- /dev/null
+++ b/app/src/routes/me/mixtapes/[slug]/+page.ts
@@ -0,0 +1,16 @@
+import { API_BASE } from '$lib/global/config';
+import type { MixtapeHydrated } from '../../../../../../shared/types/hydrated';
+
+export const load = async ({ fetch, params }) => {
+ const mixtape: MixtapeHydrated = await fetch(`${API_BASE}/mixtapes/${params.slug}`).then((res) =>
+ res.json()
+ );
+ if (!mixtape)
+ return {
+ status: 404,
+ error: new Error('Not Found')
+ };
+ return {
+ mixtape
+ };
+};