Skip to content

Commit da3b384

Browse files
committed
fix: update google auth and swagger
1 parent cf0e251 commit da3b384

22 files changed

+857
-492
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ REDIS_HOST=
88
REDIS_PORT=
99
GOOGLE_CLIENT_ID=
1010
GOOGLE_CLIENT_SECRET=
11+
GOOGLE_REDIRECT_URI=
1112
PORT=
1213
API_PREFIX=
1314
NODE_ENV=

app/config/env.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const envSchema = z.object({
1111
DATABASE_URL: z.string(),
1212
GOOGLE_CLIENT_ID: z.string(),
1313
GOOGLE_CLIENT_SECRET: z.string(),
14+
GOOGLE_REDIRECT_URI: z.string().url(),
1415
REDIS_USERNAME: z.string(),
1516
REDIS_PASSWORD: z.string(),
1617
REDIS_HOST: z.string(),

app/controllers/auth.controller.ts

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import type {
2-
GoogleAuthSchema,
2+
GoogleCodeSchema,
33
RefreshTokenSchema,
44
SigninSchema,
55
SignupSchema
66
} from '@/schemas'
7-
import type { GoogleUserResponse, JwtPayload, TypedRequestBody } from '@/types'
7+
import type { JwtPayload } from '@/types'
88
import type { NextFunction, Request, Response } from 'express'
9+
import type {
10+
TypedRequestBody,
11+
TypedRequestQuery
12+
} from 'zod-express-middleware'
913

1014
import { prisma } from '@/prisma'
1115
import { hash, verify } from 'argon2'
@@ -24,10 +28,17 @@ const {
2428
ACCESS_JWT_ALGORITHM,
2529
REFRESH_JWT_ALGORITHM,
2630
GOOGLE_CLIENT_ID,
27-
GOOGLE_CLIENT_SECRET
31+
GOOGLE_CLIENT_SECRET,
32+
GOOGLE_REDIRECT_URI
2833
} = env
2934

3035
class AuthController {
36+
googleClient = new OAuth2Client(
37+
GOOGLE_CLIENT_ID,
38+
GOOGLE_CLIENT_SECRET,
39+
GOOGLE_REDIRECT_URI
40+
)
41+
3142
signup = async (
3243
{ body }: TypedRequestBody<typeof SignupSchema>,
3344
res: Response,
@@ -84,23 +95,40 @@ class AuthController {
8495
res.json({ user: userWithoutPassword, ...tokens })
8596
}
8697

87-
google = async (
88-
{ body }: TypedRequestBody<typeof GoogleAuthSchema>,
89-
res: Response
98+
googleRedirect = async (_: Request, res: Response) => {
99+
const url = this.googleClient.generateAuthUrl({
100+
access_type: 'offline',
101+
scope: ['profile', 'email']
102+
})
103+
104+
res.redirect(url)
105+
}
106+
107+
googleCallback = async (
108+
req: TypedRequestQuery<typeof GoogleCodeSchema>,
109+
res: Response,
110+
next: NextFunction
90111
) => {
91-
const oAuth2Client = new OAuth2Client(
92-
GOOGLE_CLIENT_ID,
93-
GOOGLE_CLIENT_SECRET,
94-
'postmessage'
95-
)
112+
const { tokens } = await this.googleClient.getToken(req.query.code)
96113

97-
const { tokens } = await oAuth2Client.getToken(body.code)
114+
if (!tokens.id_token) return next(Forbidden())
98115

99-
const { name, email, picture } = await this.getUserInfoFromGoogleApi(
100-
tokens.access_token!
101-
)
116+
const ticket = await this.googleClient.verifyIdToken({
117+
idToken: tokens.id_token,
118+
audience: GOOGLE_CLIENT_ID
119+
})
102120

103-
const user = await prisma.user.findUnique({ where: { email } })
121+
const payload = ticket.getPayload()
122+
123+
if (!payload || !payload.email || !payload.name || !payload.picture) {
124+
return next(Forbidden('Invalid token'))
125+
}
126+
127+
const { name, email, picture } = payload
128+
129+
const user = await prisma.user.findUnique({
130+
where: { email }
131+
})
104132

105133
if (!user) {
106134
const user = await prisma.user.create({
@@ -131,7 +159,7 @@ class AuthController {
131159
}
132160
}
133161

134-
tokens = async (
162+
refresh = async (
135163
{ body }: TypedRequestBody<typeof RefreshTokenSchema>,
136164
res: Response,
137165
next: NextFunction
@@ -186,18 +214,6 @@ class AuthController {
186214

187215
return { accessToken, refreshToken }
188216
}
189-
190-
private getUserInfoFromGoogleApi = async (accessToken: string) => {
191-
const URL = 'https://www.googleapis.com/oauth2/v3/userinfo'
192-
193-
const r = await fetch(URL, {
194-
headers: { Authorization: `Bearer ${accessToken}` }
195-
})
196-
197-
const userInfo = (await r.json()) as GoogleUserResponse
198-
199-
return userInfo
200-
}
201217
}
202218

203219
export const authController = new AuthController()

app/controllers/board.controller.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import type {
33
BoardParamsSchema,
44
EditBoardSchema
55
} from '@/schemas'
6+
import type { NextFunction, Request, Response } from 'express'
7+
import type { ZodType } from 'zod'
68
import type {
79
TypedRequest,
810
TypedRequestBody,
911
TypedRequestParams
10-
} from '@/types'
11-
import type { NextFunction, Request, Response } from 'express'
12+
} from 'zod-express-middleware'
1213

1314
import { prisma } from '@/prisma'
1415
import { NotFound } from 'http-errors'
@@ -85,7 +86,7 @@ class BoardController {
8586
body,
8687
params,
8788
user
88-
}: TypedRequest<typeof EditBoardSchema, typeof BoardParamsSchema>,
89+
}: TypedRequest<typeof BoardParamsSchema, ZodType, typeof EditBoardSchema>,
8990
res: Response,
9091
next: NextFunction
9192
) => {

app/controllers/card.controller.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import type {
66
MoveCardSchema,
77
UpdateCardOrderSchema
88
} from '@/schemas'
9-
import type { TypedRequest, TypedRequestParams } from '@/types'
109
import type { NextFunction, Response } from 'express'
10+
import type { ZodType } from 'zod'
11+
import type { TypedRequest, TypedRequestParams } from 'zod-express-middleware'
1112

1213
import { prisma } from '@/prisma'
1314
import { BadRequest, NotFound } from 'http-errors'
@@ -19,7 +20,7 @@ class CardController {
1920
{
2021
params,
2122
body
22-
}: TypedRequest<typeof AddCardSchema, typeof ColumnParamsSchema>,
23+
}: TypedRequest<typeof ColumnParamsSchema, ZodType, typeof AddCardSchema>,
2324
res: Response,
2425
next: NextFunction
2526
) => {
@@ -45,7 +46,7 @@ class CardController {
4546
{
4647
params,
4748
body
48-
}: TypedRequest<typeof EditCardSchema, typeof CardParamsSchema>,
49+
}: TypedRequest<typeof CardParamsSchema, ZodType, typeof EditCardSchema>,
4950
res: Response,
5051
next: NextFunction
5152
) => {
@@ -72,7 +73,11 @@ class CardController {
7273
{
7374
params,
7475
body
75-
}: TypedRequest<typeof UpdateCardOrderSchema, typeof ColumnParamsSchema>,
76+
}: TypedRequest<
77+
typeof ColumnParamsSchema,
78+
ZodType,
79+
typeof UpdateCardOrderSchema
80+
>,
7681
res: Response,
7782
next: NextFunction
7883
) => {

app/controllers/column.controller.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import type {
2-
AddColumnSchema,
2+
AddBoardSchema,
33
BoardParamsSchema,
44
ColumnParamsSchema,
55
EditColumnSchema,
66
UpdateColumnOrderSchema
77
} from '@/schemas'
8-
import type { TypedRequest, TypedRequestParams } from '@/types'
98
import type { NextFunction, Response } from 'express'
9+
import type { ZodType } from 'zod'
10+
import type { TypedRequest, TypedRequestParams } from 'zod-express-middleware'
1011

1112
import { prisma } from '@/prisma'
1213
import { BadRequest, NotFound } from 'http-errors'
@@ -19,7 +20,7 @@ class ColumnController {
1920
params,
2021
user,
2122
body
22-
}: TypedRequest<typeof AddColumnSchema, typeof BoardParamsSchema>,
23+
}: TypedRequest<typeof BoardParamsSchema, ZodType, typeof AddBoardSchema>,
2324
res: Response,
2425
next: NextFunction
2526
) => {
@@ -50,7 +51,11 @@ class ColumnController {
5051
{
5152
params,
5253
body
53-
}: TypedRequest<typeof EditColumnSchema, typeof ColumnParamsSchema>,
54+
}: TypedRequest<
55+
typeof ColumnParamsSchema,
56+
ZodType,
57+
typeof EditColumnSchema
58+
>,
5459
res: Response,
5560
next: NextFunction
5661
) => {
@@ -73,7 +78,11 @@ class ColumnController {
7378
{
7479
params,
7580
body
76-
}: TypedRequest<typeof UpdateColumnOrderSchema, typeof BoardParamsSchema>,
81+
}: TypedRequest<
82+
typeof BoardParamsSchema,
83+
ZodType,
84+
typeof UpdateColumnOrderSchema
85+
>,
7786
res: Response,
7887
next: NextFunction
7988
) => {

app/controllers/user.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { EditUserSchema, NeedHelpSchema } from '@/schemas'
2-
import type { TypedRequestBody } from '@/types'
32
import type { User } from '@prisma/client'
43
import type { NextFunction, Request, Response } from 'express'
54
import type { Options } from 'nodemailer/lib/mailer'
5+
import type { TypedRequestBody } from 'zod-express-middleware'
66

77
import { prisma } from '@/prisma'
88
import { hash } from 'argon2'

app/middlewares/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
export { authenticate } from './authenticate'
22
export { upload } from './multer'
3-
export { validateRequest } from './validate-request'
43
export { notFoundHandler, globalErrorHandler } from './errorHandler'

app/middlewares/validate-request.ts

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

app/routes/api/auth.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Router } from 'express'
2+
import { validateRequest } from 'zod-express-middleware'
23

34
import { authController } from '@/controllers'
45

5-
import { authenticate, validateRequest } from '@/middlewares'
6+
import { authenticate } from '@/middlewares'
67

78
import {
8-
GoogleAuthSchema,
9+
GoogleCodeSchema,
910
RefreshTokenSchema,
1011
SigninSchema,
1112
SignupSchema
@@ -25,16 +26,18 @@ authRouter.post(
2526
authController.signin
2627
)
2728

28-
authRouter.post(
29-
'/google',
30-
validateRequest({ body: GoogleAuthSchema }),
31-
authController.google
29+
authRouter.post('/google/redirect', authController.googleRedirect)
30+
31+
authRouter.get(
32+
'/google/callback',
33+
validateRequest({ query: GoogleCodeSchema }),
34+
authController.googleCallback
3235
)
3336

3437
authRouter.post(
35-
'/tokens',
38+
'/refresh',
3639
validateRequest({ body: RefreshTokenSchema }),
37-
authController.tokens
40+
authController.refresh
3841
)
3942

4043
authRouter.post('/logout', authenticate, authController.logout)

0 commit comments

Comments
 (0)