mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-05-06 20:32:55 +08:00
feat: return address_id in /admin/new_address response (#913)
* feat: return address_id in /admin/new_address response - Add address_id field to newAddress function return type - Update CHANGELOG.md and CHANGELOG_EN.md Fixes #912 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: verify address_id in new_address response * fix: add address_id validation and improve test coverage - Add null check for address_id after DB query - Change address_id to required field in return type - Add dedicated test for /admin/new_address endpoint - Update e2e helper return type to non-optional --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
### Features
|
||||
|
||||
- feat: |Admin API| `/admin/new_address` 接口返回值新增 `address_id` 字段,避免创建后需再次查询地址 ID(#912)
|
||||
- feat: |自动回复| 发件人过滤支持正则表达式匹配,使用 `/pattern/` 语法(如 `/@example\.com$/`),同时保持前缀匹配的向后兼容
|
||||
- feat: |Turnstile| 新增全局登录表单 Turnstile 人机验证,通过 `ENABLE_GLOBAL_TURNSTILE_CHECK` 环境变量控制(#767)
|
||||
- feat: |Telegram| Telegram 推送支持发送邮件附件(单文件限制 50MB),多附件通过 `sendMediaGroup` 批量发送,通过 `ENABLE_TG_PUSH_ATTACHMENT` 环境变量开启(#894)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
### Features
|
||||
|
||||
- feat: |Admin API| `/admin/new_address` endpoint now returns `address_id` field, avoiding additional query after address creation (#912)
|
||||
- feat: |Auto Reply| Add regex matching support for sender filter using `/pattern/` syntax (e.g. `/@example\.com$/`), backward compatible with prefix matching
|
||||
- feat: |Turnstile| Add global Turnstile CAPTCHA for all login forms via `ENABLE_GLOBAL_TURNSTILE_CHECK` env var (#767)
|
||||
- feat: |Telegram| Support sending email attachments in Telegram push (50MB per file limit), multiple attachments sent via `sendMediaGroup`, controlled by `ENABLE_TG_PUSH_ATTACHMENT` env var (#894)
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function createTestAddress(
|
||||
ctx: APIRequestContext,
|
||||
name: string,
|
||||
domain: string = TEST_DOMAIN
|
||||
): Promise<{ jwt: string; address: string }> {
|
||||
): Promise<{ jwt: string; address: string; address_id: number }> {
|
||||
const uniqueName = `${name}${Date.now()}`;
|
||||
const res = await ctx.post(`${WORKER_URL}/api/new_address`, {
|
||||
data: { name: uniqueName, domain },
|
||||
@@ -25,7 +25,7 @@ export async function createTestAddress(
|
||||
throw new Error(`Failed to create address: ${res.status()} ${await res.text()}`);
|
||||
}
|
||||
const body = await res.json();
|
||||
return { jwt: body.jwt, address: body.address };
|
||||
return { jwt: body.jwt, address: body.address, address_id: body.address_id };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,9 +4,10 @@ import { WORKER_URL, TEST_DOMAIN, createTestAddress, deleteAddress, requestSendA
|
||||
test.describe('Address Lifecycle', () => {
|
||||
test('create address, request send access, fetch settings, then delete', async ({ request }) => {
|
||||
// Create address
|
||||
const { jwt, address } = await createTestAddress(request, 'lifecycle-test');
|
||||
const { jwt, address, address_id } = await createTestAddress(request, 'lifecycle-test');
|
||||
expect(address).toContain('@' + TEST_DOMAIN);
|
||||
expect(jwt).toBeTruthy();
|
||||
expect(address_id).toBeGreaterThan(0);
|
||||
|
||||
// Request send access (creates address_sender row with DEFAULT_SEND_BALANCE)
|
||||
await requestSendAccess(request, jwt);
|
||||
|
||||
19
e2e/tests/api/admin-new-address.spec.ts
Normal file
19
e2e/tests/api/admin-new-address.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { WORKER_URL, TEST_DOMAIN } from '../../fixtures/test-helpers';
|
||||
|
||||
test.describe('Admin New Address', () => {
|
||||
test('should return address_id in response', async ({ request }) => {
|
||||
const uniqueName = `admin-test${Date.now()}`;
|
||||
const res = await request.post(`${WORKER_URL}/admin/new_address`, {
|
||||
data: { name: uniqueName, domain: TEST_DOMAIN },
|
||||
});
|
||||
|
||||
expect(res.ok()).toBe(true);
|
||||
const body = await res.json();
|
||||
|
||||
expect(body.address).toContain('@' + TEST_DOMAIN);
|
||||
expect(body.jwt).toBeTruthy();
|
||||
expect(body.address_id).toBeGreaterThan(0);
|
||||
expect(typeof body.address_id).toBe('number');
|
||||
});
|
||||
});
|
||||
@@ -168,7 +168,7 @@ export const newAddress = async (
|
||||
enableCheckNameRegex?: boolean,
|
||||
sourceMeta?: string | undefined | null,
|
||||
}
|
||||
): Promise<{ address: string, jwt: string, password?: string | null }> => {
|
||||
): Promise<{ address: string, jwt: string, password?: string | null, address_id: number }> => {
|
||||
const msgs = i18n.getMessagesbyContext(c);
|
||||
// trim whitespace and remove special characters
|
||||
name = name.trim().replace(getNameRegex(c), '')
|
||||
@@ -247,6 +247,10 @@ export const newAddress = async (
|
||||
`SELECT id FROM address where name = ?`
|
||||
).bind(name).first<number>("id");
|
||||
|
||||
if (!address_id) {
|
||||
throw new Error(msgs.FailedCreateAddressMsg);
|
||||
}
|
||||
|
||||
// 如果启用地址密码功能,自动生成密码
|
||||
const generatedPassword = await generatePasswordForAddress(c, name);
|
||||
|
||||
@@ -259,6 +263,7 @@ export const newAddress = async (
|
||||
jwt: jwt,
|
||||
address: name,
|
||||
password: generatedPassword,
|
||||
address_id: address_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user