Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/booru/constants/sensitive-auth-params.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const SENSITIVE_AUTH_PARAMS = [
'user_id',
'api_key',
'password',
'password_hash',
'pass_hash',
'auth_user',
'auth_pass',
'token',
'secret',
'key',
'access_token',
'auth_token',
'session_id',
'session',
'login',
'username',
'user',
'hash'
] as const
37 changes: 13 additions & 24 deletions src/booru/dto/booru-queries.dto.spec.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
import { BadRequestException } from '@nestjs/common'
import { plainToInstance } from 'class-transformer'
import { booruQueryValuesPostsDTO } from './booru-queries.dto'

describe('booruQueryValuesPostsDTO', () => {
describe('tags transform', () => {
it('should decode URL-encoded ampersands in tags', () => {
it('should normalize a single tag string into an array', () => {
const dto = plainToInstance(booruQueryValuesPostsDTO, {
tags: 'panty_%26_stocking_with_garterbelt'
tags: 'panty_&_stocking_with_garterbelt'
})

expect(dto.tags).toEqual(['panty_&_stocking_with_garterbelt'])
})

it('should split pipe-separated tags and decode each one', () => {
it('should split pipe-separated tags', () => {
const dto = plainToInstance(booruQueryValuesPostsDTO, {
tags: 'panty_%26_stocking_with_garterbelt|rating%3Asafe'
tags: 'panty_&_stocking_with_garterbelt|rating:safe'
})

expect(dto.tags).toEqual(['panty_&_stocking_with_garterbelt', 'rating:safe'])
})

it('should normalize array tag inputs and keep tag array shape', () => {
const dto = plainToInstance(booruQueryValuesPostsDTO, {
tags: ['panty_%26_stocking_with_garterbelt|rating%3Asafe', 'score%3A%3E100']
tags: ['panty_&_stocking_with_garterbelt|rating:safe', 'score:>100']
})

expect(dto.tags).toEqual([
'panty_&_stocking_with_garterbelt',
'rating:safe',
'score:>100'
])
expect(dto.tags).toEqual(['panty_&_stocking_with_garterbelt', 'rating:safe', 'score:>100'])
})

it('should normalize non-string tag input without throwing', () => {
Expand All @@ -48,18 +43,12 @@ describe('booruQueryValuesPostsDTO', () => {
expect(dto.tags).toEqual(['100%_real'])
})

it('should throw BadRequestException when encoded tag decoding fails', () => {
expect(() =>
plainToInstance(booruQueryValuesPostsDTO, {
tags: 'bad%25%'
})
).toThrow(BadRequestException)

expect(() =>
plainToInstance(booruQueryValuesPostsDTO, {
tags: 'bad%25%'
})
).toThrow('Invalid tag encoding')
it('should keep malformed percent tag values unchanged', () => {
const dto = plainToInstance(booruQueryValuesPostsDTO, {
tags: 'bad%%'
})

expect(dto.tags).toEqual(['bad%%'])
})

it('should return undefined when tags is undefined', () => {
Expand All @@ -76,4 +65,4 @@ describe('booruQueryValuesPostsDTO', () => {
expect(dto.tags).toBeNull()
})
})
})
})
12 changes: 0 additions & 12 deletions src/booru/dto/booru-queries.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
Min
} from 'class-validator'
import { Transform } from 'class-transformer'
import { BadRequestException } from '@nestjs/common'

abstract class booruEndpointsDTO {
@IsFQDN()
Expand Down Expand Up @@ -189,17 +188,6 @@ export class booruQueryValuesPostsDTO extends booruQueriesDTO {
return (Array.isArray(value) ? value : [value])
.map((tag) => (typeof tag === 'string' ? tag : String(tag)))
.flatMap((tag) => tag.trim().split('|'))
.map((tag) => {
if (!/%[0-9A-Fa-f]{2}/.test(tag)) {
return tag
}

try {
return decodeURIComponent(tag)
} catch {
throw new BadRequestException('Invalid tag encoding')
}
})
})
@IsOptional()
readonly tags: IBooruQueryValues['posts']['tags']
Expand Down
Loading