Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions apps/web/app/api/timesheet/activity/report/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NextRequest } from 'next/server';
import { NextRequest, NextResponse } from 'next/server';
import { authenticatedGuard } from '@/core/services/server/guards/authenticated-guard-app';
import { getActivityReportRequest } from '@/core/services/server/requests/timesheet';
import { IActivityRequestParams } from '@/core/services/server/requests/timesheet';
import { ETimeLogType } from '@/core/types/generics/enums/timer';
Expand All @@ -11,7 +12,19 @@ export const runtime = 'nodejs';
* Fetches activity report data based on provided query parameters
*/
export async function GET(req: NextRequest) {
const res = new NextResponse();

try {
// Authenticate before reading parameters so anonymous callers always get 401. A session check
// that could not reach Gauzy is a 503, not a 401, so the client does not log the user out.
const guard = await authenticatedGuard(req, res);
if (!guard.user) {
return guard.unauthorized
? NextResponse.json({ message: 'Unauthorized' }, { status: 401 })
: NextResponse.json({ message: 'Session check unavailable, retry later' }, { status: 503 });
}
const { access_token } = guard;

const searchParams = req.nextUrl.searchParams;

const params: Partial<IActivityRequestParams> = {
Expand Down Expand Up @@ -63,7 +76,7 @@ export async function GET(req: NextRequest) {
}

// Fetch activity report data
const data = await getActivityReportRequest(params as IActivityRequestParams);
const { data } = await getActivityReportRequest(params as IActivityRequestParams, access_token);

return new Response(JSON.stringify(data), {
status: 200,
Expand Down
19 changes: 16 additions & 3 deletions apps/web/app/api/timesheet/time-log/report/daily/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { NextRequest } from 'next/server';
import { NextRequest, NextResponse } from 'next/server';
import { authenticatedGuard } from '@/core/services/server/guards/authenticated-guard-app';
import { getTimeLogReportDailyRequest } from '@/core/services/server/requests/timesheet';
import { ITimeLogRequestParams } from '@/core/services/server/requests/timesheet';

export const dynamic = 'force-dynamic';
export const runtime = 'nodejs';

export async function GET(req: NextRequest) {
const res = new NextResponse();

try {
// Authenticate before reading parameters so anonymous callers always get 401. A session check
// that could not reach Gauzy is a 503, not a 401, so the client does not log the user out.
const guard = await authenticatedGuard(req, res);
if (!guard.user) {
return guard.unauthorized
? NextResponse.json({ message: 'Unauthorized' }, { status: 401 })
: NextResponse.json({ message: 'Session check unavailable, retry later' }, { status: 503 });
}
const { access_token } = guard;

const searchParams = req.nextUrl.searchParams;

const params: Partial<ITimeLogRequestParams> = {
Expand Down Expand Up @@ -53,9 +66,9 @@ export async function GET(req: NextRequest) {
};
}

const response = await getTimeLogReportDailyRequest(params as ITimeLogRequestParams);
const { data } = await getTimeLogReportDailyRequest(params as ITimeLogRequestParams, access_token);

return new Response(JSON.stringify(response), {
return new Response(JSON.stringify(data), {
status: 200,
headers: {
'Content-Type': 'application/json'
Expand Down
14 changes: 12 additions & 2 deletions apps/web/core/services/server/guards/authenticated-guard-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,24 @@
const taskId = getActiveTaskIdCookie({ req, res });
const projectId = getActiveProjectIdCookie({ req, res });

// serverFetch rejects a non-2xx answer with Promise.reject(data), so Gauzy's status code sits inside
// that promise; a network failure rejects with a plain error that carries no status code.
let rejectedStatus: number | undefined;
const r_res = await currentAuthenticatedUserRequest({
bearer_token: access_token?.toString() || ''
}).catch(console.error);
}).catch(async (error: unknown) => {
const reason = error instanceof Promise ? await error.catch((data) => data) : error;

Check warning on line 26 in apps/web/core/services/server/guards/authenticated-guard-app.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

The catch parameter `data` should be named `error_`.

See more on https://sonarcloud.io/project/issues?id=ever-co_ever-teams&issues=AaB2B9UpDk5q6SaKiDPG&open=AaB2B9UpDk5q6SaKiDPG&pullRequest=4464
rejectedStatus = (reason as { statusCode?: number } | undefined)?.statusCode;
console.error(reason);
});

if (!r_res || (r_res.data as any).statusCode === 401) {
return {
$res: (data: any) => NextResponse.json({ statusCode: 401, message: data }),
user: null
user: null,
// True when Gauzy rejected the token itself; false when the check could not be completed,
// which callers should not report as 401 or the client will log the user out.
unauthorized: rejectedStatus === 401 || (r_res?.data as any)?.statusCode === 401
Comment thread
NdekoCode marked this conversation as resolved.
Outdated
};
}

Expand Down
Loading