Skip to content

Commit

Permalink
chore(core-api): Fix invalid token maybe
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitmouton committed Oct 10, 2024
1 parent 7c80807 commit 90cf3c5
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 2 deletions.
5 changes: 4 additions & 1 deletion apps/core-api/lib/lotta_web/auth/access_token.ex
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ defmodule LottaWeb.Auth.AccessToken do
{:ok, claims}

false ->
Logger.error("Invalid token type: #{inspect(claims)}")
Logger.error("Invalid token type: #{inspect(claims)}", %{
sentry: %{error: {:error, :invalid_token_type, claims}}
})

{:error, :invalid_token}
end
else
Expand Down
9 changes: 9 additions & 0 deletions apps/core-api/lib/lotta_web/auth/error_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ defmodule LottaWeb.Auth.ErrorHandler do
@impl Guardian.Plug.ErrorHandler

def auth_error(conn, {type, reason}, opts) do
Logger.warning("Auth-Header:", get_req_header(conn, "authorization"))
Logger.warning("Cookies-Header", get_req_header(conn, "cookies"))

Logger.error("Guardian error: #{inspect(type)}: #{inspect(reason)}", %{
sentry: %{error: {type, reason}}
})

Logger.debug("Guardian opts: #{inspect(opts)}")

Sentry.capture_message("Guardian error",
extra: %{
"guardian_error" => to_string(type),
Expand Down
32 changes: 32 additions & 0 deletions apps/webapp/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export const config = {
matcher: ['/((?!_next/static|_next/image|font|favicon.ico|favicon|p/).*)'],
};

const l = <T>(obj: T): T => {
// console.dir(obj, { depth: 5 });
return obj;
};

// This function can be marked `async` if using `await` inside
export async function middleware(request: NextRequest) {
if (
Expand All @@ -25,6 +30,8 @@ export async function middleware(request: NextRequest) {
accessToken: request.cookies.get('SignInAccessToken')?.value ?? null,
};

l({ authInfo });

const incomingRefreshToken = request.cookies.get('SignInRefreshToken')?.value;
const authHeader = request.headers.get('Authorization');

Expand All @@ -38,6 +45,8 @@ export async function middleware(request: NextRequest) {
console.error('Error parsing access token', e);
}

l({ accessTokenJwt });

if (!accessTokenJwt?.isValid()) {
console.warn('Access token is not valid!', accessTokenJwt);
} else if (accessTokenJwt.isExpired(0)) {
Expand All @@ -47,6 +56,8 @@ export async function middleware(request: NextRequest) {
}
}

l({ authInfoX1: authInfo });

if (incomingRefreshToken) {
let refreshTokenJwt = null;
try {
Expand All @@ -55,6 +66,8 @@ export async function middleware(request: NextRequest) {
console.error('Error parsing refresh token', e);
}

l({ refreshTokenJwt });

if (
refreshTokenJwt?.isValid() &&
// we do not need to check if the refresh token is expired (or will expire in the next seconds)
Expand All @@ -75,15 +88,20 @@ export async function middleware(request: NextRequest) {
}),
});

l({ updateRefreshTokenResult });

if (updateRefreshTokenResult) {
const { accessToken, refreshToken: updatedRefreshToken } =
updateRefreshTokenResult;

authInfo.refreshToken = updatedRefreshToken;
authInfo.accessToken = accessToken;

l({ authInfoX2: authInfo });
}
} else {
authInfo.refreshToken = incomingRefreshToken;
l({ authInfoX3: authInfo });
}
} else if (authHeader) {
console.warn('User does not have a refresh token');
Expand All @@ -95,18 +113,28 @@ export async function middleware(request: NextRequest) {
console.error('Error parsing access token', e);
}

l({ accessTokenJwt });

if (accessTokenJwt?.isValid() && !accessTokenJwt.isExpired(0)) {
authInfo.accessToken = accessToken;
}
l({ authInfoX4: authInfo });
}
}

l({ authInfoX5: authInfo });

const requestHeaders = new Headers(request.headers);
if (authInfo.accessToken) {
requestHeaders.set('Authorization', `Bearer ${authInfo.accessToken}`);
l({ requestHeaderSet: requestHeaders });
}

l({ requestHeaders });

const response = NextResponse.next({ request: { headers: requestHeaders } });

l({ authInfoX6: authInfo });
if (authInfo.refreshToken) {
try {
const parsedRefreshToken = JWT.parse(authInfo.refreshToken);
Expand All @@ -118,6 +146,8 @@ export async function middleware(request: NextRequest) {
path: '/',
});

l({ responseCookies: response.cookies });

// TODO:
// I do not think saving the access token in a cookie is a good idea
// I think a better approach would be passing it along from server components to
Expand All @@ -135,6 +165,7 @@ export async function middleware(request: NextRequest) {
expires: parsedAccessToken.body.expires,
path: '/',
});
l({ responseCookies2: response.cookies });
}
} catch (e) {
Sentry.captureException(e);
Expand All @@ -150,6 +181,7 @@ export async function middleware(request: NextRequest) {
secure: process.env.NODE_ENV === 'production',
path: '/',
});
l({ responseCookies3: response.cookies });
}

return response;
Expand Down
20 changes: 20 additions & 0 deletions apps/webapp/src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '../styles/globals.scss';

import * as React from 'react';
import * as Sentry from '@sentry/nextjs';
import { trace } from '@opentelemetry/api';
import { AppContext, AppProps } from 'next/app';
import { config as faConfig } from '@fortawesome/fontawesome-svg-core';
Expand Down Expand Up @@ -102,11 +103,22 @@ LottaWebApp.getInitialProps = async (context: AppContext) => {
},
});
});

Sentry.addBreadcrumb({
type: 'fetchedTenant',
data: { request: { headers }, result: { data: data?.tenant, error } },
});

const tenant = data?.tenant ?? null;

if (context.ctx.req) {
(context.ctx.req as any).tenant = tenant;
}

if (!tenant) {
Sentry.captureMessage('Tenant not found', {
extra: { requestBaseUrl: url },
});
return {
pageProps: {
tenant: null,
Expand All @@ -125,6 +137,10 @@ LottaWebApp.getInitialProps = async (context: AppContext) => {
},
})
);
Sentry.addBreadcrumb({
type: 'gotCurrentUser',
data: { data: userData, requestHeaders: headers },
});

const { data: categoriesData } = await trace
.getTracer('lotta-web')
Expand All @@ -136,6 +152,10 @@ LottaWebApp.getInitialProps = async (context: AppContext) => {
},
})
);
Sentry.addBreadcrumb({
type: 'gotCategoriesData',
data: { data: categoriesData, requestHeaders: headers },
});

return {
pageProps: {
Expand Down
19 changes: 18 additions & 1 deletion apps/webapp/src/pages/c/[slug].tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import * as Sentry from '@sentry/nextjs';
import { trace } from '@opentelemetry/api';
import { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import { ArticleModel, ArticleFilter, ID } from 'model';
Expand Down Expand Up @@ -32,12 +33,20 @@ export const getServerSideProps = async ({
params,
req,
}: GetServerSidePropsContext) => {
Sentry.addBreadcrumb({
type: '/c/[slug] getServerSideProps',
data: { params, req },
});
console.dir(req, { depth: 1 });

if ((req as any).tenant === null) {
return { props: {} };
throw new Error('Tenant not found');
}
const rawCategoryId = (params?.slug as string)?.replace(/^(\d+).*/, '$1');
const categoryId = rawCategoryId === '0' ? null : (rawCategoryId ?? null);

console.log({ categoryId, rawCategoryId });

const {
data: { articles },
error,
Expand All @@ -60,6 +69,14 @@ export const getServerSideProps = async ({
},
})
);
Sentry.addBreadcrumb({
type: 'gotArticles',
data: { reqHeaders: req?.headers, articles, categoryId, error },
});

if (error) {
Sentry.captureException(error);
}

return {
props: {
Expand Down

0 comments on commit 90cf3c5

Please sign in to comment.