Files
chinese-family-tree-2/test-api-csrf.js
T
freedakgmail e92884ae53 0.0.1.0
2025-11-23 03:07:39 +08:00

196 lines
5.0 KiB
JavaScript

const http = require('http');
// 简单的 HTTP 客户端来处理 cookies
class SimpleAPITester {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.cookies = new Map();
}
async request(path, options = {}) {
return new Promise((resolve, reject) => {
const url = new URL(path, this.baseUrl);
const opts = {
hostname: url.hostname,
port: url.port,
path: url.pathname + url.search,
method: options.method || 'GET',
headers: {
'Content-Type': 'application/json',
...options.headers
}
};
// 添加 cookies
if (this.cookies.size > 0) {
opts.headers.Cookie = Array.from(this.cookies.entries())
.map(([k, v]) => `${k}=${v}`)
.join('; ');
}
const req = http.request(opts, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
// 保存 cookies
if (res.headers['set-cookie']) {
res.headers['set-cookie'].forEach(cookie => {
const [nameValue] = cookie.split(';');
const [name, value] = nameValue.split('=');
if (name && value) {
this.cookies.set(name.trim(), value.trim());
}
});
}
try {
const json = JSON.parse(data);
resolve({ status: res.statusCode, data: json, headers: res.headers });
} catch {
resolve({ status: res.statusCode, data, headers: res.headers });
}
});
});
req.on('error', reject);
if (options.body) {
req.write(JSON.stringify(options.body));
}
req.end();
});
}
async register(email, password, name) {
console.log('📝 注册用户...');
const response = await this.request('/api/auth/register', {
method: 'POST',
body: { email, password, name }
});
console.log(`状态: ${response.status}`);
console.log(response.data);
return response;
}
async getCSRFToken() {
console.log('🔐 获取 CSRF token...');
const response = await this.request('/api/auth/signin');
const csrfCookie = this.cookies.get('next-auth.csrf-token');
if (csrfCookie) {
const [token] = csrfCookie.split('|');
return token;
}
return null;
}
async login(email, password) {
console.log('🔑 登录...');
const csrfToken = await this.getCSRFToken();
if (!csrfToken) {
throw new Error('无法获取 CSRF token');
}
const response = await this.request('/api/auth/signin', {
method: 'POST',
body: {
email,
password,
csrfToken,
redirect: false
}
});
return response;
}
async createTree(name, description) {
console.log('🌳 创建家族树...');
const response = await this.request('/api/trees', {
method: 'POST',
body: { name, description }
});
console.log(`状态: ${response.status}`);
console.log(response.data);
return response;
}
async getTrees() {
console.log('📋 获取家族树列表...');
const response = await this.request('/api/trees');
console.log(`状态: ${response.status}`);
console.log(JSON.stringify(response.data, null, 2));
return response;
}
async createMember(treeId, memberData) {
console.log('👤 创建成员...');
const response = await this.request(`/api/trees/${treeId}/members`, {
method: 'POST',
body: memberData
});
console.log(`状态: ${response.status}`);
console.log(response.data);
return response;
}
async getMembers(treeId) {
console.log('👥 获取成员列表...');
const response = await this.request(`/api/trees/${treeId}/members`);
console.log(`状态: ${response.status}`);
console.log(JSON.stringify(response.data, null, 2));
return response;
}
}
async function runTests() {
const tester = new SimpleAPITester('http://localhost:3000');
try {
console.log('🚀 开始完整 API 测试...\n');
// 1. 注册用户
await tester.register('api-test@example.com', 'password123', 'API测试用户');
console.log('');
// 2. 登录
await tester.login('api-test@example.com', 'password123');
console.log('');
// 3. 创建家族树
const treeResponse = await tester.createTree('API测试家族树', '通过API创建');
console.log('');
if (treeResponse.status === 201) {
const treeId = treeResponse.data.tree.id;
// 4. 获取家族树列表
await tester.getTrees();
console.log('');
// 5. 创建成员
await tester.createMember(treeId, {
surname: '李',
givenName: '明',
fullName: '李明',
gender: 'MALE',
generation: 1,
birthDate: '1990-01-01'
});
console.log('');
// 6. 获取成员列表
await tester.getMembers(treeId);
console.log('');
}
console.log('✅ 所有测试完成!');
} catch (error) {
console.error('❌ 测试失败:', error);
}
}
runTests();