feat: add endpoint to update payer with bearer token validation and input validation
This commit is contained in:
		
							parent
							
								
									28e14224e7
								
							
						
					
					
						commit
						cc4c5c5ad4
					
				| 
						 | 
				
			
			@ -101,6 +101,48 @@ app.use(route.get('/payer', async (ctx) => {
 | 
			
		|||
	ctx.body = payers
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
app.use(route.put('/payer/:id', async (ctx, id) => {
 | 
			
		||||
	// 请求头验证 bearer token
 | 
			
		||||
	const bearerToken = ctx.request.headers['authorization']?.split(' ')
 | 
			
		||||
	if (!bearerToken) throw new HttpError(ErrorDescEnum.unauthorized, 401)
 | 
			
		||||
	if (bearerToken[0] !== 'Bearer') throw new HttpError(ErrorDescEnum.unauthorized, 401)
 | 
			
		||||
	if (!bearerToken[1]) throw new HttpError(ErrorDescEnum.unauthorized, 401)
 | 
			
		||||
	await func.verifyBearerToken(bearerToken[1])
 | 
			
		||||
 | 
			
		||||
	// 验证 id 必须是数字
 | 
			
		||||
	if (isNaN(parseInt(id))) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['id'])
 | 
			
		||||
 | 
			
		||||
	// 验证必填字段
 | 
			
		||||
	// 字段缺失时
 | 
			
		||||
	if (!ctx.request.body) throw new HttpError(ErrorDescEnum.required_fields_missing, 400, ['name', 'address', 'email'])
 | 
			
		||||
 | 
			
		||||
	// 有字段,但为空时
 | 
			
		||||
	const { name, address, email, abn } = ctx.request.body
 | 
			
		||||
	let emptyFields = []
 | 
			
		||||
	if (!name) emptyFields.push('name')
 | 
			
		||||
	if (!address) emptyFields.push('address')
 | 
			
		||||
	if (!email) emptyFields.push('email')
 | 
			
		||||
	if (emptyFields.length > 0) throw new HttpError(ErrorDescEnum.required_fields_missing, 400, emptyFields)
 | 
			
		||||
 | 
			
		||||
	// 验证地址格式,格式应为 string[],最多两行
 | 
			
		||||
	if (!Array.isArray(address) || address.length > 2 || address.length <= 0) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['address'])
 | 
			
		||||
 | 
			
		||||
	// 名字应为字符串
 | 
			
		||||
	if (typeof name !== 'string') throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['name'])
 | 
			
		||||
	
 | 
			
		||||
	// 验证邮箱格式
 | 
			
		||||
	const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
 | 
			
		||||
	if (!emailRegex.test(email)) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['email'])
 | 
			
		||||
 | 
			
		||||
	// 验证 ABN 格式
 | 
			
		||||
	const abnRegex = /^\d{11}$/
 | 
			
		||||
	if (abn && !abnRegex.test(abn)) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['abn'])
 | 
			
		||||
 | 
			
		||||
	// 更新付款人
 | 
			
		||||
	await func.updatePayer(ctx.prisma, id, name, address, email, abn)
 | 
			
		||||
	ctx.status = 204
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
app.use(route.post('/invoice', async (ctx) => {
 | 
			
		||||
	// 请求头验证 bearer token
 | 
			
		||||
	const bearerToken = ctx.request.headers['authorization']?.split(' ')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import verifyBearerToken from "./verifyBearerToken"
 | 
			
		|||
import getSpecificInvoice from "./getSpecificInvoice"
 | 
			
		||||
import getInvoices from "./getInvoices"
 | 
			
		||||
import getPayers from "./getPayers"
 | 
			
		||||
import updatePayer from "./updatePayer"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	createPayer,
 | 
			
		||||
| 
						 | 
				
			
			@ -12,4 +13,5 @@ export default {
 | 
			
		|||
	getSpecificInvoice,
 | 
			
		||||
	getInvoices,
 | 
			
		||||
	getPayers,
 | 
			
		||||
	updatePayer
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								backend/src/func/updatePayer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								backend/src/func/updatePayer.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
import { PrismaClient } from '@prisma/client'
 | 
			
		||||
import { ErrorDescEnum, HttpError } from '../classes/HttpError'
 | 
			
		||||
 | 
			
		||||
export default async function updatePayer(prisma: PrismaClient, id: number, name: string, address: string[], email: string, abn?: string) {
 | 
			
		||||
	// 验证 ABN 是否已存在
 | 
			
		||||
	const existingPayer = await prisma.payer.findFirst({
 | 
			
		||||
		where: {
 | 
			
		||||
			payer_abn: abn
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	if (existingPayer && existingPayer.payer_id !== id) {
 | 
			
		||||
		// 验证 abn 是否已经是当前付款人的 abn
 | 
			
		||||
		if (existingPayer.payer_id !== id) throw new HttpError(ErrorDescEnum.item_exists, 400, ['abn'])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 验证付款人是否存在
 | 
			
		||||
	const payerExists = await prisma.payer.findFirst({
 | 
			
		||||
		where: {
 | 
			
		||||
			payer_id: id
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	if (!payerExists) throw new HttpError(ErrorDescEnum.item_not_found, 404, ['payer'])
 | 
			
		||||
 | 
			
		||||
	// 更新付款人
 | 
			
		||||
	const payer = await prisma.payer.update({
 | 
			
		||||
		where: {
 | 
			
		||||
			payer_id: id
 | 
			
		||||
		},
 | 
			
		||||
		data: {
 | 
			
		||||
			payer_name: name,
 | 
			
		||||
			payer_address: address.join('\n'),
 | 
			
		||||
			payer_email: email,
 | 
			
		||||
			payer_abn: abn
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return payer
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user