• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DiogoAngelim / openai-oauth / 20805281641

08 Jan 2026 04:14AM UTC coverage: 74.21% (-19.0%) from 93.204%
20805281641

push

github

DiogoAngelim
fix: remove unsupported --config from drizzle-kit generate:sqlite

133 of 229 branches covered (58.08%)

Branch coverage included in aggregate %.

313 of 372 relevant lines covered (84.14%)

4.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.84
/apps/backend/src/auth/auth.controller.ts
1
import { URLSearchParams } from 'url'
7✔
2
import {
7✔
3
  Controller,
4
  Get,
5
  Req,
6
  Res,
7
  UseGuards,
8
  Post,
9
  UnauthorizedException
10
} from '@nestjs/common'
11
// import { User } from '@prisma/client'; // Remove Prisma import
12
import { AuthGuard } from '@nestjs/passport'
7✔
13
import { AuthService } from './auth.service'
7✔
14
import { Response, Request as ExpressRequest } from 'express'
15

16
// Define a user type compatible with your Drizzle schema
17
interface User {
18
  id: string
19
  image?: string | null
20
  name?: string | null
21
  email: string
22
  createdAt?: Date
23
  updatedAt?: Date
24
}
25

26
// Extend Express Request to include user property
27
interface AuthenticatedRequest extends ExpressRequest {
28
  user?: {
29
    user?: Partial<User>
30
    org?: { id?: string } | null
31
    membership?: { role?: string; organizationId?: string }
32
  }
33
}
34

35
@Controller('auth')
36
export class AuthController {
7✔
37
  constructor(private readonly authService: AuthService) { }
7✔
38

39
  @Get('google')
40
  @UseGuards(AuthGuard('google'))
41
  async googleAuth(): Promise<void> { }
7✔
42

43
  @Get('google/callback')
44
  @UseGuards(AuthGuard('google'))
45
  async googleAuthCallback(
7✔
46
    @Req() req: AuthenticatedRequest,
47
    @Res() res: Response
48
  ): Promise<void> {
49
    // Debug: print req.user and its properties
50
    console.log('googleAuthCallback req.user:', JSON.stringify(req.user, null, 2))
×
51
    if (
×
52
      req.user === undefined ||
×
53
      req.user === null ||
54
      req.user.user === undefined ||
55
      req.user.user === null ||
56
      typeof req.user.user !== 'object' ||
57
      req.user.membership === undefined ||
58
      req.user.membership === null ||
59
      typeof req.user.membership !== 'object'
60
    ) {
61
      console.error('Invalid user payload:', JSON.stringify(req.user, null, 2))
×
62
      throw new UnauthorizedException('Invalid user payload')
×
63
    }
64
    const { user, org, membership } = req.user
×
65
    // Ensure user has all required fields for generateTokens
66
    const userObj = user as User
×
67
    const userForToken = {
×
68
      id: userObj.id ?? '',
×
69
      image: userObj.image ?? null,
×
70
      name: userObj.name ?? null,
×
71
      email: userObj.email ?? '',
×
72
      createdAt: userObj.createdAt ?? new Date(),
×
73
      updatedAt: userObj.updatedAt ?? new Date()
×
74
    }
75
    const tokens = await this.authService.generateTokens(
×
76
      userForToken,
77
      membership.organizationId ?? '',
×
78
      membership.role ?? ''
×
79
    )
80
    res.cookie('refresh_token', tokens.refreshToken, {
×
81
      httpOnly: true,
82
      secure: true,
83
      sameSite: 'lax',
84
      maxAge: 1000 * 60 * 60 * 24 * 30
85
    })
86
    // Redirect to frontend with access token in query string
87
    const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3001'
×
88
    const params = new URLSearchParams({
×
89
      accessToken: tokens.accessToken,
90
      user: JSON.stringify(user),
91
      org: org ? JSON.stringify(org) : '',
×
92
      role: membership.role ?? ''
×
93
    })
94
    res.redirect(`${frontendUrl}/auth/callback?${params.toString()}`)
×
95
  }
96

97
  @Post('refresh')
98
  async refresh(
7✔
99
    @Req() req: AuthenticatedRequest,
100
    @Res() res: Response
101
  ): Promise<void> {
102
    let refreshToken: string | undefined
103
    if (
×
104
      req.cookies !== undefined &&
×
105
      req.cookies !== null &&
106
      typeof req.cookies === 'object' &&
107
      req.cookies.refresh_token !== undefined &&
108
      req.cookies.refresh_token !== null &&
109
      typeof req.cookies.refresh_token === 'string'
110
    ) {
111
      refreshToken = req.cookies.refresh_token
×
112
    } else if (
×
113
      req.body !== undefined &&
×
114
      req.body !== null &&
115
      typeof req.body === 'object' &&
116
      req.body.refreshToken !== undefined &&
117
      req.body.refreshToken !== null &&
118
      typeof req.body.refreshToken === 'string'
119
    ) {
120
      refreshToken = req.body.refreshToken
×
121
    }
122
    if (
×
123
      refreshToken === undefined ||
×
124
      refreshToken === null ||
125
      typeof refreshToken !== 'string' ||
126
      refreshToken.trim().length === 0
127
    ) {
128
      throw new UnauthorizedException('No refresh token')
×
129
    }
130
    const tokens = await this.authService.refreshAccessToken(refreshToken)
×
131
    res.json({ accessToken: tokens.accessToken })
×
132
  }
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc