Skip to content

Commit 4eb9409

Browse files
committed
feat: ui part call and match found / sign out button / sameet controllers
1 parent ace7501 commit 4eb9409

6 files changed

Lines changed: 61 additions & 75 deletions

File tree

frontend/app/home/page.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -549,15 +549,15 @@ export default function FindMatchPage() {
549549
)}
550550

551551
{matchFound && (
552-
<div className="relative min-h-screen flex items-center justify-center px-4 py-14 sm:py-16 md:py-6">
552+
<div className="relative min-h-screen flex items-center justify-center px-4 py-4 sm:py-16 md:py-4">
553553
<button
554554
onClick={handleBackFromMatch}
555-
className="absolute top-7 left-10 flex font-semibold text-primary"
555+
className="absolute top-7 left-10 hidden md:flex font-semibold text-primary"
556556
>
557557
<ChevronLeft size={23} className="mt-0.5" />
558558
Go Back
559559
</button>
560-
<div className="w-full max-w-4xl mx-auto text-center space-y-8 sm:space-y-5">
560+
<div className="w-full max-w-4xl mx-auto text-center space-y-4 sm:space-y-5">
561561
<div className="space-y-3 sm:space-y-3">
562562
<div className="inline-flex items-center gap-2 sm:gap-3 px-4 sm:px-6 py-1.5 sm:py-2 bg-linear-to-r from-primary to-favor text-white rounded-full shadow-md sm:shadow-lg">
563563
<Zap className="w-4 h-4 sm:w-5 sm:h-5" />
@@ -566,7 +566,7 @@ export default function FindMatchPage() {
566566
</span>
567567
</div>
568568

569-
<h2 className="font-sans text-2xl sm:text-4xl md:text-6xl font-bold text-foreground leading-tight">
569+
<h2 className="font-sans text-xl sm:text-2xl md:text-4xl font-bold text-foreground leading-tight">
570570
Meet Your New Connection
571571
</h2>
572572

frontend/app/session/page.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -654,16 +654,8 @@ function VideoCallInner() {
654654
<span className="text-white/15 text-xs font-mono">{iceState}</span>
655655
</header>
656656

657-
{/* ── Video area ── */}
658-
{/*
659-
h-full is critical: section must have explicit height so absolute
660-
children (controls, local video) are positioned within the viewport.
661-
Without it, section collapses to 0 and controls overflow below screen.
662-
Layout mirrors Google Meet: remote video fills section, controls float
663-
over video at bottom, local video sits just above controls on the right.
664-
*/}
657+
665658
<section className="flex-1 relative h-full overflow-hidden">
666-
{/* Remote video — fills entire section */}
667659
<video
668660
ref={remoteVideoRef}
669661
autoPlay
@@ -709,10 +701,9 @@ function VideoCallInner() {
709701

710702
{/* Local video PiP — top-right on mobile, bottom-right on sm+ */}
711703
<div
712-
className="absolute top-16 right-3 sm:bottom-20 sm:top-auto sm:right-4 z-30 w-34 sm:w-44 md:w-52 xl:w-72 rounded-xl overflow-hidden"
704+
className="absolute top-16 right-3 sm:bottom-20 sm:top-auto sm:right-4 z-30 w-24 sm:w-44 md:w-52 xl:w-72 rounded-xl overflow-hidden [aspect-ratio:3/4] sm:[aspect-ratio:16/9]"
713705
style={{
714706
border: '1px solid rgba(255,255,255,0.1)',
715-
aspectRatio: '16/9',
716707
}}
717708
>
718709
<video

frontend/components/ProfileIcon.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ export default function ProfileHover() {
7373

7474
<div className="h-px bg-slate-200 dark:bg-slate-800 my-2 mx-2" />
7575

76-
<button className="w-full flex items-center justify-between p-2.5 rounded-xl text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20 transition-all group">
77-
<div className="flex items-center gap-3" onClick={handleLogout}>
76+
<button
77+
onClick={handleLogout}
78+
className="w-full flex items-center justify-between p-2.5 rounded-xl text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20 transition-all group"
79+
>
80+
<div className="flex items-center gap-3">
7881
<LogOut
7982
size={16}
8083
className="group-hover:rotate-12 transition-transform"

gateway/src/proxies/authProxy.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import { ClientRequest, IncomingMessage } from 'node:http';
33
import dotenv from 'dotenv';
44
dotenv.config();
55

6+
const isProduction = process.env.NODE_ENV === 'production';
7+
68
export const authProxy = createProxyMiddleware({
79
target: `${process.env.AUTH_SERVICE_URL}/auth`,
810
changeOrigin: true,
11+
cookieDomainRewrite: isProduction ? { '*': '.conferoo.in' } : '',
912

1013
on: {
1114
proxyReq: (proxyReq: ClientRequest, req: IncomingMessage) => {

services/auth-service/src/controllers/authController.ts

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@ import { authService } from '../services/authServices.js';
33
import { googleAuthService } from '../services/googleAuth.service.js';
44
import { logger } from '../config/logger.js';
55
import { AppError } from '../middlewares/errorHandller.js';
6-
import { authSessionRepository } from '../repositories/authSessionRepository.js';
7-
import { hashRefreshToken } from '../utils/jwtService.js';
86
import { redis } from '../config/redis.js';
7+
import { hashRefreshToken } from '../utils/jwtService.js';
8+
import { authSessionRepository } from '../repositories/authSessionRepository.js';
99

1010
const isProduction = process.env.NODE_ENV === 'production';
1111

12+
const cookieOptions = (maxAge: number) => ({
13+
httpOnly: true,
14+
secure: isProduction,
15+
sameSite: (isProduction ? 'none' : 'lax') as 'none' | 'lax',
16+
path: '/',
17+
maxAge,
18+
...(isProduction && { domain: '.conferoo.in' }),
19+
});
20+
1221
export const register = async (req: Request, res: Response) => {
1322
const { email, password, fullName } = req.body;
1423
const verificationToken = await authService.registerUser(
@@ -55,12 +64,6 @@ export const login = async (req: Request, res: Response) => {
5564
const { accessToken, refreshToken, role, userId } =
5665
await authService.loginUser(email, password);
5766

58-
// ── Single-device login block ─────────────────────────────────────────────
59-
// Check if this user already has an active socket (online:{userId} exists).
60-
// Both services share the same Redis instance so this check is reliable.
61-
// If online → reject with 409 and return userId so frontend can force logout.
62-
// The user must force-logout the other device before they can log in here.
63-
// ─────────────────────────────────────────────────────────────────────────
6467
const alreadyOnline = await redis.exists(`online:${userId}`);
6568
if (alreadyOnline) {
6669
logger.info(`Login blocked — user ${userId} already online`);
@@ -74,29 +77,17 @@ export const login = async (req: Request, res: Response) => {
7477

7578
logger.info('Login Succesfull');
7679

77-
res.cookie('refreshToken', refreshToken, {
78-
httpOnly: true,
79-
secure: false,
80-
sameSite: 'lax',
81-
domain: 'localhost',
82-
path: '/',
83-
maxAge: 7 * 24 * 60 * 60 * 1000,
84-
});
85-
86-
res.cookie('accessToken', accessToken, {
87-
httpOnly: true,
88-
secure: false,
89-
sameSite: 'lax',
90-
domain: 'localhost',
91-
path: '/',
92-
maxAge: 24 * 60 * 60 * 1000,
93-
});
80+
res.cookie(
81+
'refreshToken',
82+
refreshToken,
83+
cookieOptions(7 * 24 * 60 * 60 * 1000)
84+
);
85+
res.cookie('accessToken', accessToken, cookieOptions(24 * 60 * 60 * 1000));
9486

9587
res.status(200).json({
9688
message: 'Login Successfully Completed',
9789
success: true,
9890
role,
99-
userId,
10091
});
10192
};
10293

@@ -120,32 +111,33 @@ export const resendOtp = async (req: Request, res: Response) => {
120111
export const googleLogin = async (req: Request, res: Response) => {
121112
const { idToken } = req.body;
122113

123-
const { accessToken, refreshToken } =
114+
const { accessToken, refreshToken, role, userId } =
124115
await googleAuthService.authenticate(idToken);
125116

126-
logger.info('Google login successful');
117+
const alreadyOnline = await redis.exists(`online:${userId}`);
118+
if (alreadyOnline) {
119+
logger.info(`Login blocked — user ${userId} already online`);
120+
return res.status(409).json({
121+
success: false,
122+
message: 'You are already logged in on another device or tab.',
123+
code: 'ALREADY_LOGGED_IN',
124+
userId,
125+
});
126+
}
127127

128-
res.cookie('refreshToken', refreshToken, {
129-
httpOnly: true,
130-
secure: false,
131-
sameSite: 'lax',
132-
domain: 'localhost',
133-
path: '/',
134-
maxAge: 7 * 24 * 60 * 60 * 1000,
135-
});
128+
logger.info('Google login successful');
136129

137-
res.cookie('accessToken', accessToken, {
138-
httpOnly: true,
139-
secure: false,
140-
sameSite: 'lax',
141-
domain: 'localhost',
142-
path: '/',
143-
maxAge: 24 * 60 * 60 * 1000,
144-
});
130+
res.cookie(
131+
'refreshToken',
132+
refreshToken,
133+
cookieOptions(7 * 24 * 60 * 60 * 1000)
134+
);
135+
res.cookie('accessToken', accessToken, cookieOptions(24 * 60 * 60 * 1000));
145136

146137
res.status(200).json({
147138
success: true,
148139
message: 'Google login successfully completed',
140+
role,
149141
});
150142
};
151143

@@ -208,17 +200,16 @@ export const logout = async (req: Request, res: Response) => {
208200

209201
await authService.logoutUser(refreshToken);
210202

211-
res.clearCookie('refreshToken', {
203+
const clearOptions = {
212204
httpOnly: true,
213-
sameSite: 'lax',
214205
secure: isProduction,
215-
});
206+
sameSite: (isProduction ? 'none' : 'lax') as 'none' | 'lax',
207+
path: '/',
208+
...(isProduction && { domain: '.conferoo.in' }),
209+
};
216210

217-
res.clearCookie('accessToken', {
218-
httpOnly: true,
219-
sameSite: 'lax',
220-
secure: isProduction,
221-
});
211+
res.clearCookie('refreshToken', clearOptions);
212+
res.clearCookie('accessToken', clearOptions);
222213

223214
res.status(200).json({
224215
success: true,
@@ -234,11 +225,7 @@ export const refresh = async (req: Request, res: Response) => {
234225

235226
const newAccessToken = await authService.refreshAccessToken(refreshToken);
236227

237-
res.cookie('accessToken', newAccessToken, {
238-
httpOnly: true,
239-
secure: isProduction,
240-
sameSite: 'lax',
241-
});
228+
res.cookie('accessToken', newAccessToken, cookieOptions(24 * 60 * 60 * 1000));
242229

243230
res.status(200).json({
244231
message: 'refresh succesfully',
@@ -257,4 +244,4 @@ export const resetPassword = async (req: Request, res: Response) => {
257244
const { token, newPassword } = req.body;
258245
await authService.resetPassword(token, newPassword);
259246
res.json({ message: 'Password updated successfully' });
260-
};
247+
};

services/auth-service/src/services/googleAuth.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export const googleAuthService = {
6767
return {
6868
accessToken,
6969
refreshToken,
70+
role:user.role,
71+
userId
7072
};
7173
},
7274
};

0 commit comments

Comments
 (0)