Skip to content

Commit

Permalink
feat(auth): clear old / stale cookies when decryption fails
Browse files Browse the repository at this point in the history
  • Loading branch information
vladjerca authored and seferturan committed Jan 10, 2025
1 parent 9677637 commit 37ca829
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
53 changes: 34 additions & 19 deletions projects/client/src/lib/features/auth/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,29 @@ import { encrypt } from './utils/encrypt.ts';
const AUTH_COOKIE_NAME = 'trakt-auth';

export const handle: Handle = async ({ event, resolve }) => {
/**
* TODO: refresh exchange flow here
* https://trakt.docs.apiary.io/#reference/authentication-oauth/get-token/exchange-refresh_token-for-access_token
*/
const setAuth = (auth: ClientAuthResponse | Nil) => {
const setAuth = (auth: SerializedAuthResponse | Nil) => {
event.locals.auth = auth;
};

const encrypted = event.cookies.get(AUTH_COOKIE_NAME);
encrypted && setAuth(await decrypt(key, encrypted));
const isLogout = event.url.pathname.startsWith(AuthEndpoint.Logout);

if (isLogout) {
setAuth(null);
return new Response(null, {
headers: {
'Set-Cookie': event.cookies.serialize(AUTH_COOKIE_NAME, '', {
httpOnly: true,
secure: true,
maxAge: 0,
path: '/',
}),
},
});
}

if (event.url.pathname.startsWith(AuthEndpoint.Exchange)) {
const isExchange = event.url.pathname.startsWith(AuthEndpoint.Exchange);

if (isExchange) {
const { code } = await event.request.json() as { code: string };
const referrer = event.request.headers.get('referer') ?? '';

Expand Down Expand Up @@ -55,17 +66,21 @@ export const handle: Handle = async ({ event, resolve }) => {
);
}

if (event.url.pathname.startsWith(AuthEndpoint.Logout)) {
setAuth(null);
return new Response(null, {
headers: {
'Set-Cookie': event.cookies.serialize(AUTH_COOKIE_NAME, '', {
httpOnly: true,
secure: true,
maxAge: 0,
path: '/',
}),
},
/**
* TODO: refresh exchange flow here
* https://trakt.docs.apiary.io/#reference/authentication-oauth/get-token/exchange-refresh_token-for-access_token
*/
const encrypted = event.cookies.get(AUTH_COOKIE_NAME);
const decrypted = await decrypt<SerializedAuthResponse>(key, encrypted);
const isDecryptionFailed = decrypted == null && encrypted != null;
setAuth(decrypted);

if (isDecryptionFailed) {
event.cookies.set(AUTH_COOKIE_NAME, '', {
httpOnly: true,
secure: true,
maxAge: 0,
path: '/',
});
}

Expand Down
6 changes: 5 additions & 1 deletion projects/client/src/lib/features/auth/utils/decrypt.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export async function decrypt<T>(
key: CryptoKey,
data: string,
data: string | Nil,
): Promise<T | Nil> {
if (!data) {
return null;
}

try {
const encryptedBuffer = new Uint8Array(
atob(data)
Expand Down

0 comments on commit 37ca829

Please sign in to comment.