Skip to content

Commit

Permalink
Merge pull request #67 from kimitrii/kimitri
Browse files Browse the repository at this point in the history
refactor(RefreshTokenHandler): Send accessToken in Bearer Header for Refresh Token API and Fix Type Errors
  • Loading branch information
kimitrii authored Feb 14, 2025
2 parents 6b14517 + 768629a commit 26e8624
Show file tree
Hide file tree
Showing 14 changed files with 47 additions and 123 deletions.
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,10 @@ This endpoint refreshes an expired access token by validating the provided refre
> |--------------|-----------|------------------------------------------------------------------------------------------------------|
> | Content-Type | yes | Required for operations with a request body. The value is application/. Where the 'format' is 'json'.|
> | X-CSRF-Token | yes | A CSRF token to protect against cross-site request forgery attacks. Must be included in the request.|
> | Authorization | yes | Access Token, a Bearer token in the format `Bearer <JWT>` for authenticating the request and ensuring access.|
**Note**: The `refreshToken` is automatically sent by the browser in the `Cookie` header if the client has a valid session. It does not need to be manually set in the request.
> #### Body Schema
> | name | type | Required | description |
> |---------------|-----------|----------|-------------------------------------|
> | accessToken | string |**yes** | The current expired JWT access token. |
#### Response
> #### Sample Successful Response
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/auth/users/GenerateOtpAuth.Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const GenerateOtpAuthUrlHandler = factory.createHandlers(
otpRepository
)

const id = c.req.param('id')
const id = c.req.param('id') ?? ''

const otpUrl = await generateOtpAuthUrlService.execute({ id })

Expand Down
15 changes: 5 additions & 10 deletions src/handlers/auth/users/RefreshToken.Handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ISanitizedAuthDTO } from '@src/dtos/Auth.DTO'
import { AppError } from '@src/errors/AppErrors.Error'
import { WebCryptoAES } from '@src/lib/webCryptoAES'
import { RefreshTokenRepository } from '@src/repositories/auth/RefreshToken.Repository'
import { JWTManager } from '@src/services/auth/jwtManager/JWTManager.Service'
Expand Down Expand Up @@ -34,18 +33,14 @@ export const RefreshTokenHandler = factory.createHandlers(
webCryptoAES
)

const accessToken = await c.req.json().catch(() => {
throw new AppError({
name: 'Bad Request',
message: 'Invalid JSON format in request body'
})
})
const authorization = c.req.header('authorization') ?? ''
const accessToken = authorization.split(' ')[1]

const userAgent = c.req.header('User-Agent')
const userAgent = c.req.header('User-Agent') ?? ''

const refreshToken = getCookie(c, 'refreshToken')
const refreshToken = getCookie(c, 'refreshToken') ?? ''

const data = { refreshToken, userAgent, ...accessToken }
const data = { refreshToken, userAgent, accessToken }

const user = await refreshTokenService.execute(data)

Expand Down
4 changes: 2 additions & 2 deletions src/handlers/error/Errors.Handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Context } from 'hono'
import { HTTPException } from 'hono/http-exception'
import type { HTTPResponseError } from 'hono/types'
import type { StatusCode } from 'hono/utils/http-status'
import type { ContentfulStatusCode } from 'hono/utils/http-status'
import {
JwtAlgorithmNotImplemented,
JwtHeaderInvalid,
Expand All @@ -16,7 +16,7 @@ export const errorsHandler = (
error: Error | HTTPResponseError,
c: Context
): Response | Promise<Response> => {
const errorMap: Record<string, { status: StatusCode }> = {
const errorMap: Record<string, { status: ContentfulStatusCode }> = {
'Bad Request': { status: 400 },
Unauthorized: { status: 401 },
Forbidden: { status: 403 },
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/users/DeleteUser/DeleteUser.Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const DeleteUserHandler = factory.createHandlers(
const usersRepository = new UserRepository(c.env.DB)
const deleteUserService = new DeleteUserService(usersRepository)

const id = c.req.param('id')
const id = c.req.param('id') ?? ''

const data = { id }

Expand Down
2 changes: 1 addition & 1 deletion src/handlers/users/GetUserById/GetUserById.Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const GetUserByIdHandler = factory.createHandlers(
const usersRepository = new UserRepository(c.env.DB)
const getUserByIdService = new GetUserByIdService(usersRepository)

const id = c.req.param('id')
const id = c.req.param('id') ?? ''

const queryParameters = c.req.query('includeDeleted')

Expand Down
8 changes: 2 additions & 6 deletions tests/handlers/auth/refreshToken/NotFound.failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ describe('Refresh Token not found failure cases E2E', () => {
env.REFRESH_SECRET_KEY
)

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -51,9 +47,9 @@ describe('Refresh Token not found failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down
16 changes: 4 additions & 12 deletions tests/handlers/auth/refreshToken/Signature.failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ describe('Refresh Token signature failure cases E2E', () => {
env.REFRESH_SECRET_KEY
)

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -51,9 +47,9 @@ describe('Refresh Token signature failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down Expand Up @@ -87,10 +83,6 @@ describe('Refresh Token signature failure cases E2E', () => {
const accessTokenGen = await sign(payloadAccessToken, env.USER_SECRET_KEY)
const refreshTokenGen = await sign(payloadRefreshToken, 'invalid-signature')

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -99,9 +91,9 @@ describe('Refresh Token signature failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down
8 changes: 2 additions & 6 deletions tests/handlers/auth/refreshToken/SubMatch.failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ describe('Refresh Token Sub Match failure cases E2E', () => {
env.REFRESH_SECRET_KEY
)

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -51,9 +47,9 @@ describe('Refresh Token Sub Match failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down
8 changes: 2 additions & 6 deletions tests/handlers/auth/refreshToken/Success.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,6 @@ describe('Refresh Token success cases handler E2E', () => {

await db.insert(refreshToken).values(refreshTokenInstances)

const payload = JSON.stringify({
accessToken: generatedAccessToken
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -115,9 +111,9 @@ describe('Refresh Token success cases handler E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${generatedAccessToken}`,
Cookie: `refreshToken=${generatedRefreshToken}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down
16 changes: 4 additions & 12 deletions tests/handlers/auth/refreshToken/TokenExp.failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ describe('Refresh Token expired failure cases E2E', () => {
env.REFRESH_SECRET_KEY
)

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -51,9 +47,9 @@ describe('Refresh Token expired failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down Expand Up @@ -90,10 +86,6 @@ describe('Refresh Token expired failure cases E2E', () => {
env.REFRESH_SECRET_KEY
)

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -102,9 +94,9 @@ describe('Refresh Token expired failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down
8 changes: 2 additions & 6 deletions tests/handlers/auth/refreshToken/TokenStatus.failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ describe('Refresh Token status failure cases E2E', () => {

await db.insert(refreshToken).values(refreshTokenInstance)

const payload = JSON.stringify({
accessToken: accessTokenGen
})

const res = await app.request(
'/users/auth/refresh',
{
Expand All @@ -102,9 +98,9 @@ describe('Refresh Token status failure cases E2E', () => {
'Content-Type': 'application/json',
'X-CSRF-Token': 'mock-csrf-token',
'User-Agent': 'Vitest',
Authorization: `Bearer ${accessTokenGen}`,
Cookie: `refreshToken=${refreshTokenGen}; Max-Age=2332800; Path=/users/auth/refresh; HttpOnly; Secure; SameSite=Strict`
},
body: payload
}
},
env
)
Expand Down
Loading

0 comments on commit 26e8624

Please sign in to comment.