Skip to content

Commit f85027f

Browse files
authored
Merge pull request #1291 from trycompai/claudio/fix-portal
[dev] [claudfuen] claudio/fix-portal
2 parents 23d4f16 + e61a94b commit f85027f

File tree

6 files changed

+88
-603
lines changed

6 files changed

+88
-603
lines changed

apps/api/src/auth/hybrid-auth.guard.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ export class HybridAuthGuard implements CanActivate {
2222
return this.handleApiKeyAuth(request, apiKey);
2323
}
2424

25-
// Try JWT Bearer authentication (for internal frontend with JWT tokens)
25+
// Try Bearer JWT token authentication (for internal frontend)
2626
const authHeader = request.headers['authorization'] as string;
2727
if (authHeader?.startsWith('Bearer ')) {
2828
return this.handleJwtAuth(request, authHeader);
2929
}
3030

3131
throw new UnauthorizedException(
32-
'Authentication required: Provide X-API-Key or Authorization Bearer JWT token',
32+
'Authentication required: Provide either X-API-Key or Bearer JWT token',
3333
);
3434
}
3535

@@ -61,56 +61,56 @@ export class HybridAuthGuard implements CanActivate {
6161
authHeader: string,
6262
): Promise<boolean> {
6363
try {
64-
// Extract JWT token from Bearer header
65-
const token = authHeader.replace('Bearer ', '');
64+
// Extract token from "Bearer <token>"
65+
const token = authHeader.substring(7);
6666

67-
// Verify JWT using Better Auth JWKS endpoint
67+
// Create JWKS for token verification using Better Auth endpoint
6868
const JWKS = createRemoteJWKSet(
6969
new URL(`${process.env.BETTER_AUTH_URL}/api/auth/jwks`),
7070
);
7171

72+
// Verify JWT token
7273
const { payload } = await jwtVerify(token, JWKS, {
7374
issuer: process.env.BETTER_AUTH_URL,
7475
audience: process.env.BETTER_AUTH_URL,
7576
});
7677

77-
// Extract user information from JWT payload
78-
// By default, Better Auth includes the entire user object in the payload
79-
const user = payload.user as { id: string; email: string };
80-
if (!user?.id) {
78+
// Extract user information from JWT payload (user data is directly in payload for Better Auth JWT)
79+
const userId = payload.id as string;
80+
const userEmail = payload.email as string;
81+
82+
if (!userId) {
8183
throw new UnauthorizedException(
8284
'Invalid JWT payload: missing user information',
8385
);
8486
}
8587

86-
// Require explicit organization ID via header for JWT auth
87-
const organizationId = request.headers['x-organization-id'] as string;
88-
if (!organizationId) {
88+
// JWT authentication REQUIRES explicit X-Organization-Id header
89+
const explicitOrgId = request.headers['x-organization-id'] as string;
90+
91+
if (!explicitOrgId) {
8992
throw new UnauthorizedException(
90-
'Organization context required: Provide X-Organization-Id header for JWT authentication',
93+
'Organization context required: X-Organization-Id header is mandatory for JWT authentication',
9194
);
9295
}
9396

94-
// Critical: Verify user has access to the requested organization
95-
const hasAccess = await this.verifyUserOrgAccess(user.id, organizationId);
97+
// Verify user has access to the requested organization
98+
const hasAccess = await this.verifyUserOrgAccess(userId, explicitOrgId);
9699
if (!hasAccess) {
97100
throw new UnauthorizedException(
98-
`User does not have access to organization: ${organizationId}`,
101+
`User does not have access to organization: ${explicitOrgId}`,
99102
);
100103
}
101104

102105
// Set request context for JWT auth
103-
request.userId = user.id;
104-
request.userEmail = user.email;
105-
request.organizationId = organizationId;
106+
request.userId = userId;
107+
request.userEmail = userEmail;
108+
request.organizationId = explicitOrgId;
106109
request.authType = 'jwt';
107110
request.isApiKey = false;
108111

109112
return true;
110-
} catch (error: unknown) {
111-
if (error instanceof UnauthorizedException) {
112-
throw error;
113-
}
113+
} catch (error) {
114114
console.error('JWT verification failed:', error);
115115
throw new UnauthorizedException('Invalid or expired JWT token');
116116
}

apps/api/src/auth/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Types removed - using JWT authentication only
1+
// Types for API authentication - supports API keys and JWT tokens only
22

33
export interface AuthenticatedRequest extends Request {
44
organizationId: string;
@@ -12,6 +12,6 @@ export interface AuthContext {
1212
organizationId: string;
1313
authType: 'api-key' | 'jwt';
1414
isApiKey: boolean;
15-
userId?: string; // Only available for jwt auth
16-
userEmail?: string; // Only available for jwt auth
15+
userId?: string; // Only available for JWT auth
16+
userEmail?: string; // Only available for JWT auth
1717
}

apps/app/buildspec.yml

Lines changed: 0 additions & 249 deletions
This file was deleted.

0 commit comments

Comments
 (0)