Skip to content

Commit

Permalink
feat(auth): add auth headers in client
Browse files Browse the repository at this point in the history
  • Loading branch information
seferturan committed Feb 12, 2025
1 parent 82d7191 commit 0155428
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 5 deletions.
2 changes: 1 addition & 1 deletion projects/client/src/hooks.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ export const handle: Handle = sequence(
},
handleCacheControl,
handleMobileOperatingSystem,
handleGateway,
handleGateway, // TODO remove March 31st
);
2 changes: 2 additions & 0 deletions projects/client/src/lib/features/auth/stores/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AuthEndpoint } from '$lib/features/auth/AuthEndpoint.ts';
import { setToken } from '$lib/features/auth/token/index.ts';
import { InvalidateAction } from '$lib/requests/models/InvalidateAction.ts';
import { useInvalidator } from '$lib/stores/useInvalidator.ts';
import { assertDefined } from '$lib/utils/assert/assertDefined.ts';
Expand Down Expand Up @@ -39,6 +40,7 @@ export function useAuth() {
await fetch(AuthEndpoint.Logout, {
method: 'POST',
});
setToken(null);
isAuthorized.set(false);
await invalidate(InvalidateAction.Auth);
globalThis.location.href = setCacheBuster(
Expand Down
13 changes: 13 additions & 0 deletions projects/client/src/lib/features/auth/token/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const token: {
value: string | Nil;
} = {
value: null,
};

export function getToken() {
return token.value;
}

export function setToken(value: string | Nil) {
token.value = value;
}
9 changes: 7 additions & 2 deletions projects/client/src/lib/features/gateway/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ export const handle: Handle = async ({ event, resolve }) => {
const url = new URL(event.request.url);

if (url.pathname.startsWith(ClientEnvironment.svelte)) {
const headers = new Headers(event.request.headers);
const authorizationHeader = headers.get('Authorization');

if (authorizationHeader) {
return resolve(event);
}

const traktUrl = new URL(
url.pathname.replace(ClientEnvironment.svelte, ''),
TRAKT_TARGET_ENVIRONMENT,
Expand All @@ -17,8 +24,6 @@ export const handle: Handle = async ({ event, resolve }) => {

const token = event.locals.auth?.token?.access;

const headers = new Headers(event.request.headers);

if (token) {
headers.set('Authorization', `Bearer ${token}`);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { getToken } from '$lib/features/auth/token/index.ts';
import { error } from '$lib/utils/console/print.ts';

export function createAuthenticatedFetch<
T extends typeof fetch,
>(baseFetch: T): T {
return (function authenticatedFetch(
input: Parameters<T>[0],
init?: Parameters<T>[1],
): Promise<Response> {
const modifiedInit = { ...init } as Parameters<T>[1];
const headers = new Headers(modifiedInit?.headers || {});

try {
const token = getToken();

if (token) {
headers.set('Authorization', `Bearer ${token}`);
}

return baseFetch(
input,
{
...modifiedInit,
headers,
} as Parameters<T>[1],
);
} catch (e) {
error('Fetch interceptor error:', e);
return baseFetch(input, init);
}
}) as unknown as T;
}
3 changes: 2 additions & 1 deletion projects/client/src/lib/requests/api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createAuthenticatedFetch } from '$lib/requests/_internal/createAuthenticatedFetch.ts';
import { IS_TEST } from '$lib/utils/env/index.ts';
import { traktApi, type TraktApiOptions } from '@trakt/api';

Expand Down Expand Up @@ -27,7 +28,7 @@ export const api = ({
traktApi({
apiKey: TRAKT_CLIENT_ID,
environment,
fetch,
fetch: createAuthenticatedFetch(fetch),
cancellable,
cancellationId,
});
12 changes: 11 additions & 1 deletion projects/client/src/routes/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { AUTH_COOKIE_NAME } from '$lib/features/auth/handle.ts';
import { setToken } from '$lib/features/auth/token/index.ts';
import { isAuthorized } from '$lib/features/auth/utils/isAuthorized.ts';
import { buildOAuthUrl } from '$lib/utils/url/buildOAuthLink.ts';
import { isBotAgent } from '$lib/utils/url/isBotAgent.ts';
import type { LayoutServerLoad } from './$types.ts';

export const load: LayoutServerLoad = (
{ request, locals },
{ cookies, request, locals },
) => {
const requestUrl = new URL(request.url);

Expand All @@ -13,9 +15,17 @@ export const load: LayoutServerLoad = (
auth: {
url: buildOAuthUrl(TRAKT_CLIENT_ID, requestUrl.origin),
isAuthorized: isAuthorized(locals),
token: null as string | Nil,
},
isBot: isBotAgent(request.headers.get('user-agent')),
};

if (!locals.auth) {
setToken(null);
cookies.delete(AUTH_COOKIE_NAME, { path: '/' });
return defaultResponse;
}

defaultResponse.auth.token = locals.auth.token.access;
return defaultResponse;
};
3 changes: 3 additions & 0 deletions projects/client/src/routes/+layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { LayoutLoad } from './$types.ts';

import { browser } from '$app/environment';
import { currentUserSettingsQuery } from '$lib/features/auth/queries/currentUserSettingsQuery.ts';
import { setToken } from '$lib/features/auth/token/index.ts';
import { QueryClient } from '@tanstack/svelte-query';

export const load: LayoutLoad = async ({ data, fetch }) => {
Expand All @@ -16,6 +17,8 @@ export const load: LayoutLoad = async ({ data, fetch }) => {
},
});

setToken(data.auth.token);

if (data.auth.isAuthorized) {
await queryClient.prefetchQuery(currentUserSettingsQuery({ fetch }));
}
Expand Down
7 changes: 7 additions & 0 deletions projects/client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ export default defineConfig(({ mode }) => ({
fs: {
allow: [MONOREPO_ROOT],
},
proxy: {
'/_api': {
target: TRAKT_TARGET_ENVIRONMENT,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/_api\/trakt/, ''),
},
},
},

plugins: [
Expand Down

0 comments on commit 0155428

Please sign in to comment.