Skip to content

Commit

Permalink
feat(auth): add required deletedAt to DELETE /tenant body
Browse files Browse the repository at this point in the history
  • Loading branch information
BlairCurrey committed Dec 5, 2024
1 parent 8e51dff commit 0bab0c4
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
17 changes: 16 additions & 1 deletion packages/auth/src/shared/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Config } from '../config/app'
import { createContext } from '../tests/context'
import { generateApiSignature } from '../tests/apiSignature'
import { initIocContainer } from '..'
import { verifyApiSignature } from './utils'
import { verifyApiSignature, isValidDateString } from './utils'
import { TestContainer, createTestApp } from '../tests/app'

describe('utils', (): void => {
Expand Down Expand Up @@ -145,4 +145,19 @@ describe('utils', (): void => {
expect(verified).toBe(false)
})
})

describe('isValidDateString', () => {
test.each([
['2024-12-05T15:10:09.545Z', true],
['2024-12-05', true],
['invalid-date', false], // Invalid date string
['2024-12-05T25:10:09.545Z', false], // Invalid date string (invalid hour)
['"2024-12-05T15:10:09.545Z"', false], // Improperly formatted string
['', false], // Empty string
[null, false], // Null value
[undefined, false] // Undefined value
])('should return %p for input %p', (input, expected) => {
expect(isValidDateString(input!)).toBe(expected)
})
})
})
5 changes: 5 additions & 0 deletions packages/auth/src/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,8 @@ export async function verifyApiSignature(

return verifyApiSignatureDigest(signature as string, ctx.request, config)
}

// Intended for Date strings like "2024-12-05T15:10:09.545Z" (e.g., from new Date().toISOString())
export function isValidDateString(date: string): boolean {
return !isNaN(Date.parse(date))
}
2 changes: 2 additions & 0 deletions packages/auth/src/tenant/routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ describe('Tenant Routes', (): void => {
id: tenant.id
}
)
ctx.request.body = { deletedAt: new Date().toISOString() }

await expect(tenantRoutes.delete(ctx)).resolves.toBeUndefined()
expect(ctx.status).toBe(204)
Expand All @@ -217,6 +218,7 @@ describe('Tenant Routes', (): void => {
id: v4()
}
)
ctx.request.body = { deletedAt: new Date().toISOString() }

await expect(tenantRoutes.delete(ctx)).resolves.toBeUndefined()
expect(ctx.status).toBe(404)
Expand Down
10 changes: 9 additions & 1 deletion packages/auth/src/tenant/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AppContext } from '../app'
import { TenantService } from './service'
import { BaseService } from '../shared/baseService'
import { Tenant } from './model'
import { isValidDateString } from '../shared/utils'

type TenantRequest<BodyT = never, QueryT = ParsedUrlQuery> = Exclude<
AppContext['request'],
Expand Down Expand Up @@ -40,7 +41,7 @@ interface TenantResponse {
export type GetContext = TenantContext<never, TenantParams>
export type CreateContext = TenantContext<CreateTenantBody>
export type UpdateContext = TenantContext<UpdateTenantBody, TenantParams>
export type DeleteContext = TenantContext<never, TenantParams>
export type DeleteContext = TenantContext<{ deletedAt: string }, TenantParams>

export interface TenantRoutes {
get(ctx: GetContext): Promise<void>
Expand Down Expand Up @@ -103,6 +104,13 @@ async function deleteTenant(
ctx: DeleteContext
): Promise<void> {
const { id } = ctx.params
const { deletedAt: deletedAtString } = ctx.request.body

if (!isValidDateString(deletedAtString)) {
ctx.status = 400
return
}

const deleted = await deps.tenantService.delete(id)

if (!deleted) {
Expand Down

0 comments on commit 0bab0c4

Please sign in to comment.