Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c0ddb7a
trainingLocation renamed to workLocation
abhishek2021005 Dec 11, 2025
7c38053
acl checks in diff apis and filter jobs by recruiter
abhishek2021005 Dec 11, 2025
201f092
org info modal
abhishek2021005 Dec 11, 2025
9dd1be3
job portal entry page flickering, userId replaced with email in invit…
abhishek2021005 Dec 15, 2025
0a092f9
Merge remote-tracking branch 'origin/main' into finalJp
abhishek2021005 Dec 15, 2025
e70ad87
Merge remote-tracking branch 'origin' into finalJP
Dec 19, 2025
32573b0
applicant action change in create-job-application api
Dec 22, 2025
2985550
update-job-application api modification acc to table jobApplicationAc…
Dec 22, 2025
0c29b30
application action corrected on frontend
Dec 22, 2025
ab78e2b
cleaned ununsed components
Dec 22, 2025
633ca2d
accept,reject offer modification acc to table jobApplicationAction
Dec 22, 2025
4dc2b02
application-timeline api, with its imlementation on UI
Dec 23, 2025
2ffa66c
build fix
Dec 23, 2025
655d0dd
autofill value while registering and form validation
Dec 23, 2025
cd5fae7
minor fix
Dec 23, 2025
4996d32
internship period calculation fix
Dec 24, 2025
8b55fdb
endpoints to backend helper functions,profileCompletion Popup,review…
Dec 24, 2025
d3331b6
Merge remote-tracking branch 'origin' into finalJP
Dec 24, 2025
c20b3cf
minor
Dec 24, 2025
740879d
login check using double cookie mechanism
abhishek2021005 Dec 30, 2025
b47cc39
removed getAuthHeaders passing from all api endpoints
abhishek2021005 Dec 30, 2025
e50820d
header passing mechanism to lmp apis
abhishek2021005 Dec 30, 2025
f8e5cae
Merge remote-tracking branch 'origin' into finalJP
abhishek2021005 Dec 30, 2025
b346024
minor build fix
abhishek2021005 Dec 30, 2025
ce6222e
env variable fix
abhishek2021005 Dec 30, 2025
2496870
delete cookie handled from backend
abhishek2021005 Dec 31, 2025
2e09630
Merge remote-tracking branch 'origin/main' into finalJP
abchugh Jan 8, 2026
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
14 changes: 5 additions & 9 deletions packages/alea-frontend/components/DrillConfigurator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ import {
BloomDimension,
CardsWithSmileys,
SmileyLevel,
getAuthHeaders,
isLoggedIn,
smileyToLevel,
} from '@alea/spec';
import { SafeHtml } from '@alea/react-utils';
import { SafeHtml, useIsLoggedIn } from '@alea/react-utils';
import { ConfigureLevelSlider } from '@alea/stex-react-renderer';
import { PRIMARY_COL, SECONDARY_COL, Window, stableShuffle } from '@alea/utils';
import axios from 'axios';
Expand Down Expand Up @@ -175,7 +173,7 @@ function CoverageConfigurator({
}
setCheckedChapterIdxs(newChecked);
};
const loggedIn = isLoggedIn();
const loggedIn = useIsLoggedIn();
const router = useRouter();
const { flashCards: t } = getLocaleObject(router);

Expand Down Expand Up @@ -291,7 +289,7 @@ function ReviseAndDrillButtons({
shuffle: boolean;
setShuffle: (r: boolean) => void;
}) {
const loggedIn = isLoggedIn();
const loggedIn = useIsLoggedIn();
const isDisabled = selectedCards.length === 0;
const router = useRouter();
const { flashCards: t } = getLocaleObject(router);
Expand Down Expand Up @@ -378,7 +376,7 @@ export function DrillConfigurator({ courseId }: { courseId: string }) {
const [mode, setMode] = useState(FlashCardMode.REVISION_MODE);
const [shuffle, setShuffle] = useState(true);

const loggedIn = isLoggedIn();
const loggedIn = useIsLoggedIn();

const sectionCounts = getSectionCounts(levels, loggedIn, courseCards);
const selectedChapters = checkedChapterIdxs.map((idx) => sectionCounts[idx].sectionTitle);
Expand All @@ -388,9 +386,7 @@ export function DrillConfigurator({ courseId }: { courseId: string }) {
if (!courseId) return;
setIsLoading(true);
axios
.get(`/api/get-cards-with-smileys/${courseId}`, {
headers: getAuthHeaders(),
})
.get(`/api/get-cards-with-smileys/${courseId}`)
.then((r) => {
setIsLoading(false);
setCourseCards(r.data);
Expand Down
5 changes: 2 additions & 3 deletions packages/alea-frontend/components/FlashCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ import {
SmileyCognitiveValues,
SmileyType,
getUriSmileys,
isLoggedIn,
smileyToLevel,
} from '@alea/spec';
import { SafeHtml } from '@alea/react-utils';
import { SafeHtml, useIsLoggedIn } from '@alea/react-utils';
import {
FixedPositionMenu,
LayoutWithFixedMenu,
Expand Down Expand Up @@ -73,7 +72,7 @@ export function FlashCardFooter({
needUpdateMarker: any;
onFlip: () => void;
}) {
const loggedIn = isLoggedIn();
const loggedIn = useIsLoggedIn();
const { locale } = useRouter();
const { flashCards: t } = getLocaleObject({ locale });
return (
Expand Down
6 changes: 3 additions & 3 deletions packages/alea-frontend/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import HelpIcon from '@mui/icons-material/Help';
import WarningIcon from '@mui/icons-material/Warning';
import { Box, Button, IconButton, Menu, MenuItem, Toolbar, Tooltip } from '@mui/material';
import AppBar from '@mui/material/AppBar';
import { getUserInfo, isLoggedIn, logout } from '@alea/spec';
import { CountryFlag, useScrollDirection } from '@alea/react-utils';
import { getUserInfo, logout } from '@alea/spec';
import { CountryFlag, useIsLoggedIn } from '@alea/react-utils';
import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
Expand Down Expand Up @@ -129,7 +129,7 @@ function LanguageButton() {
}

export function Header({ headerBgColor }: { headerBgColor?: string }) {
const loggedIn = isLoggedIn();
const loggedIn = useIsLoggedIn();
const router = useRouter();
const { header: t } = getLocaleObject(router);
const background = headerBgColor
Expand Down
19 changes: 9 additions & 10 deletions packages/alea-frontend/components/NotificationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ import {
NotificationType,
getNotificationSeenTime,
getUserNotifications,
isLoggedIn,
updateNotificationSeenTime,
} from '@alea/spec';
import { DateView } from '@alea/react-utils';
import { DateView, useIsLoggedIn } from '@alea/react-utils';
import { PRIMARY_COL, localStore } from '@alea/utils';
import Link from 'next/link';
import { useRouter } from 'next/router';
Expand Down Expand Up @@ -113,20 +112,20 @@ function NotificationButton({ bgColor }: { bgColor?: string }) {
// System info menu crap end

const sortedItems = useNotificationData();

const isLoggedIn = useIsLoggedIn();
useEffect(() => {
if (isLoggedIn()) {
if (isLoggedIn) {
getNotificationSeenTime().then(setNotificationSeenTime);
}
}, []);
}, [isLoggedIn]);

function topUpdate() {
if (!sortedItems?.length) return '';
return new Date(sortedItems[0].postedTimestamp).getTime().toString();
}

function shouldRing(topUpdate) {
if (!isLoggedIn()) {
if (!isLoggedIn) {
const lastNotificationSeenTime = localStore?.getItem('notification-seen-time');
return lastNotificationSeenTime !== topUpdate;
} else {
Expand All @@ -136,7 +135,7 @@ function NotificationButton({ bgColor }: { bgColor?: string }) {

async function handleUpdate(e) {
setAnchorEl(e.currentTarget);
if (!isLoggedIn()) {
if (!isLoggedIn) {
localStore?.setItem('notification-seen-time', topUpdate());
} else {
setNotificationSeenTime(topUpdate());
Expand All @@ -158,9 +157,9 @@ function NotificationButton({ bgColor }: { bgColor?: string }) {
sx={{ '& .MuiMenu-list': { pb: 0 } }}
>
{sortedItems.slice(0, 7).map((item, idx) => (
<Link
key={`${item.link}-${item.postedTimestamp}`}
href={item.link}
<Link
key={`${item.link}-${item.postedTimestamp}`}
href={item.link}
target={getLinkTarget(item.notificationType)}
>
<MenuItem onClick={handleClose}>
Expand Down
4 changes: 3 additions & 1 deletion packages/alea-frontend/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { initialize } from '@flexiformal/ftml-react';
import { createInstance, MatomoProvider } from '@jonkoops/matomo-tracker-react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { AppProps } from 'next/app';
import { CommentRefreshProvider } from '@alea/react-utils';
import { CommentRefreshProvider, IsLoggedInProvider } from '@alea/react-utils';
import { useEffect, useState } from 'react';
import { CurrentTermProvider } from '../contexts/CurrentTermContext';
import './styles.scss';
Expand Down Expand Up @@ -109,6 +109,7 @@ function CustomApp({ Component, pageProps }: AppProps) {
<MathJaxContext>
<FTMLReadyContext.Provider value={readyToRender}>
<PositionProvider>
<IsLoggedInProvider>
<CurrentTermProvider>
<div
style={{
Expand All @@ -121,6 +122,7 @@ function CustomApp({ Component, pageProps }: AppProps) {
<Component {...pageProps} />
</div>
</CurrentTermProvider>
</IsLoggedInProvider>
</PositionProvider>
</FTMLReadyContext.Provider>
</MathJaxContext>
Expand Down
14 changes: 6 additions & 8 deletions packages/alea-frontend/pages/api/comment-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
Comment,
NotificationType,
PointsGrant,
lmpResponseToUserInfo
} from '@alea/spec';
import { Comment, NotificationType, PointsGrant, lmpResponseToUserInfo } from '@alea/spec';
import axios from 'axios';
import { NextApiRequest, NextApiResponse } from 'next';
import mysql from 'serverless-mysql';
Expand Down Expand Up @@ -103,8 +98,11 @@ export async function executeTxnAndEndSet500OnError(
}

export async function getUserInfo(req: NextApiRequest) {
if (!req.headers.authorization) return undefined;
const headers = { Authorization: req.headers.authorization };
const token = req.cookies?.access_token;
if (!token) return undefined;
const headers = {
Authorization: `JWT ${token}`,
};
const lmpServerAddress = process.env.NEXT_PUBLIC_AUTH_SERVER_URL;
const resp = await axios.get(`${lmpServerAddress}/getuserinfo`, { headers });
return lmpResponseToUserInfo(resp.data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)

const cookieOptions = [
`access_token=${record.jwtToken}`,
/* TODO: Uncomment this when we can handle httpOnly cookies.
'HttpOnly',
'Secure',
'SameSite=Lax',*/
'SameSite=Strict',
'Path=/',
`Max-Age=${365 * 24 * 60 * 60}`, // 1 year
`Max-Age=${180 * 24 * 60 * 60}`, // 6 months
].join('; ');

res.setHeader('Set-Cookie', cookieOptions).send('Authentication successful');
Expand Down
7 changes: 6 additions & 1 deletion packages/alea-frontend/pages/api/fake-login/[userId].ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export default async function handler(
access_token = access_token?.split(';')[0];
if (access_token.startsWith(ACCESS_TOKEN_PREFIX))
access_token = access_token.substring(ACCESS_TOKEN_PREFIX.length);
//TODO: add secure as well once we are on https
res.setHeader('Set-Cookie', [
`access_token=${access_token}; HttpOnly; Path=/; SameSite=Strict; Max-Age=15552000;`,
`is_logged_in=true; Path=/; SameSite=Strict; Max-Age=15552000;`,
]);

res.status(200).json({ access_token });
res.status(200).end();
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { contentToc } from '@flexiformal/ftml-backend';
import { FTML } from '@flexiformal/ftml';
import { CardsWithSmileys, getDefiniedaInSection, getDefiniedaInSectionAgg, getUriSmileys } from '@alea/spec';
import {
CardsWithSmileys,
getDefiniedaInSectionAgg,
getUriSmileyInternal,
SmileyCognitiveValues,
} from '@alea/spec';
import { getAllCoursesFromDb } from '../get-all-courses';
import { lmpRedirect } from '../lmp-redirect';

export const EXCLUDED_CHAPTERS = ['Preface', 'Administrativa', 'Resources'];
const CARDS_CACHE: { [courseId: string]: CourseCards } = {};
Expand Down Expand Up @@ -54,10 +60,26 @@ export async function getCardsBySection(notesUri: string) {
});
return courseCards;
}
async function getUriSmileysBackend(concepts: string[], token: string) {
const data = await lmpRedirect(
'lmp',
'lmp/output/multiple',
'POST',
null,
{
concepts,
'special-output': '5StepLikertSmileys',
'include-confidence': false,
},
token
);

return getUriSmileyInternal(data, concepts);
}

export default async function handler(req, res) {
const { courseId } = req.query;
const Authorization = req.headers.authorization;
const token = req.cookies?.access_token;
const courses = await getAllCoursesFromDb();
const courseInfo = courses[courseId];
if (!courseInfo) {
Expand All @@ -74,10 +96,13 @@ export default async function handler(req, res) {
for (const chapter of Object.keys(cards)) {
conceptUris.push(...(cards[chapter]?.cardUris.map((c) => c.conceptUri) || []));
}
const smileyValues = Authorization
? await getUriSmileys(conceptUris, { Authorization })
: new Map();

let smileyValues: Map<string, SmileyCognitiveValues>;
try {
smileyValues = token ? await getUriSmileysBackend(conceptUris, token) : new Map();
} catch (err) {
console.error('Error fetching smiley values from LMP:', err);
return res.status(500).send('Error fetching smiley values');
}
const output: CardsWithSmileys[] = [];
for (const sectionTitle of Object.keys(cards)) {
const { chapterTitle, cardUris } = cards[sectionTitle];
Expand Down
10 changes: 8 additions & 2 deletions packages/alea-frontend/pages/api/gpt-redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function apiNameToPath(apiName: string, projectName?: string): string {

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { method, body, headers } = req;
const { method, body } = req;
const { apiname, projectName, ...otherQueryParams } = req.query; // The URL to forward the request to

if (!apiname || typeof apiname !== 'string') {
Expand All @@ -20,7 +20,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const url = `${apiNameToPath(apiname, projectName as string)}${
queryString ? `?${queryString}` : ''
}`;

const token = req.cookies?.access_token;
const headers: Record<string, string> = {
'Content-Type': 'application/json',
};
if (token) {
headers.Authorization = `JWT ${token}`;
}
const axiosConfig = {
method: method as Method,
url,
Expand Down
16 changes: 16 additions & 0 deletions packages/alea-frontend/pages/api/is-logged-in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { getUserId } from './comment-utils';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const token = req.cookies.access_token;
try {
if (!token || !(await getUserId(req))) throw new Error('No token or invalid user');
return res.status(200).json({ isLoggedIn: true });
} catch (err) {
res.setHeader('Set-Cookie', [
'access_token=; HttpOnly; Path=/; SameSite=Lax; Max-Age=0',
'is_logged_in=; Path=/; SameSite=Lax; Max-Age=0',
]);
return res.status(200).json({ loggedIn: false });
}
}
56 changes: 56 additions & 0 deletions packages/alea-frontend/pages/api/lmp-redirect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import axios, { AxiosError } from 'axios';
import type { NextApiRequest, NextApiResponse } from 'next';
import { checkIfPostOrSetError } from './comment-utils';

const SERVER_TO_ADDRESS = {
lmp: process.env['NEXT_PUBLIC_LMP_URL'],
auth: process.env['NEXT_PUBLIC_AUTH_SERVER_URL'],
};

export async function lmpRedirect(
server: 'lmp' | 'auth',
apiUrl: string,
requestType: 'GET' | 'POST',
defaultVal: any,
data?: any,
token?: string
) {
if (!token) return defaultVal;
const headers = {
Authorization: `JWT ${token}`,
};
const serverAddress = SERVER_TO_ADDRESS[server];
const fullUrl = `${serverAddress}/${apiUrl}`;
const resp =
requestType === 'POST'
? await axios.post(fullUrl, data, { headers })
: await axios.get(fullUrl, { headers });
return resp.data;
}

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (!checkIfPostOrSetError(req, res)) return;
try {
const { server, apiUrl, requestType, defaultVal, data } = req.body;
const token = req.cookies?.access_token;
const result = await lmpRedirect(
server,
apiUrl,
requestType,
defaultVal,
data,
token
);
return res.status(200).json(result);
} catch (err) {
const error = err as Error | AxiosError;
if (axios.isAxiosError(error)) {
return res.status(error.response?.status || 500).json({
error: error.response?.data || 'Internal Server Error',
});
} else {
console.error('LMP Redirect Error:', error);
return res.status(500).json({ error: 'Internal Server Error' });
}
}
}
Loading