template-monorepo/test/k6/smoke/auth_login_mfa.js

82 lines
2.3 KiB
JavaScript
Raw Normal View History

2026-05-26 17:10:32 +00:00
// smoke: POST /api/v1/auth/login/mfa
//
// Covers:
// login → mfa_required已啟用 TOTP 時不回 token
// 403 — TOTP 錯誤29505000
// 404 — challenge 不存在28301000
// 403 — tenant slug 不符28505000
// 400 — 缺少 code / challenge_id
//
// Happy pathlogin → login/mfa → JWT見 journeys/login_mfa_full.js
import { post, checkError } from '../lib/http.js';
import { cfg } from '../lib/config.js';
import { registerAndConfirm, loginExpectMFA } from '../lib/auth.js';
import { enrollTOTP } from '../lib/member.js';
export const options = {
vus: 1,
iterations: 1,
thresholds: { checks: ['rate==1.0'] },
};
export default function () {
const { identity, tokens } = registerAndConfirm();
const bearer = { Authorization: `Bearer ${tokens.access_token}` };
const { otpauthUrl } = enrollTOTP(bearer);
const mfa = loginExpectMFA({
email: identity.email,
password: identity.password,
});
if (mfa.access_token) {
throw new Error('login with TOTP enrolled should not return access_token');
}
// bad TOTP
checkError(
post('/api/v1/auth/login/mfa', {
tenant_slug: cfg.tenantSlug,
challenge_id: mfa.mfa_challenge_id,
code: '000000',
}),
'POST /auth/login/mfa (bad totp)',
403,
29505000,
);
// unknown challenge — Redis miss 目前回 50028201000
checkError(
post('/api/v1/auth/login/mfa', {
tenant_slug: cfg.tenantSlug,
challenge_id: '00000000-0000-0000-0000-000000000000',
code: '123456',
}),
'POST /auth/login/mfa (unknown challenge)',
500,
28201000,
);
// unknown tenant slugresolveTenant 失敗)
checkError(
post('/api/v1/auth/login/mfa', {
tenant_slug: 'wrong-tenant-slug',
challenge_id: mfa.mfa_challenge_id,
code: '123456',
}),
'POST /auth/login/mfa (unknown tenant)',
404,
29301000,
);
// missing fields
const missing = post('/api/v1/auth/login/mfa', { tenant_slug: cfg.tenantSlug });
if (missing.status !== 400) {
throw new Error(`login/mfa missing fields: expected 400 got ${missing.status}`);
}
// otpauthUrl kept for journey reuse sanity (not used further in smoke)
if (!otpauthUrl) {
throw new Error('enrollTOTP did not return otpauthUrl');
}
}