97 lines
4.1 KiB
JavaScript
97 lines
4.1 KiB
JavaScript
// smoke: public auth endpoints (no Bearer)
|
|
//
|
|
// Covers:
|
|
// POST /api/v1/auth/register (happy → challenge_id)
|
|
// POST /api/v1/auth/register/resend (happy → new challenge_id)
|
|
// POST /api/v1/auth/login (negative → invalid credentials)
|
|
// POST /api/v1/auth/token/refresh (negative → invalid refresh token)
|
|
// POST /api/v1/auth/register/social/start (happy → oauth_url)
|
|
// POST /api/v1/auth/login/social/start (happy → oauth_url)
|
|
// GET /api/v1/auth/register/social/callback (negative → invalid state)
|
|
// GET /api/v1/auth/login/social/callback (negative → invalid state)
|
|
//
|
|
// Note: social callback happy path requires browser redirect (skipped — see README).
|
|
import { sleep } from 'k6';
|
|
import { get, post, checkEnvelope, checkError, checkErrorOneOf } from '../lib/http.js';
|
|
import { cfg, unique } from '../lib/config.js';
|
|
import { registerEmail, resendRegister } from '../lib/auth.js';
|
|
|
|
export const options = {
|
|
vus: 1,
|
|
iterations: 1,
|
|
thresholds: { checks: ['rate==1.0'] },
|
|
};
|
|
|
|
export default function () {
|
|
// 1. register happy
|
|
const email = `${unique('smoke-pub')}@k6.local`;
|
|
const reg = registerEmail({ email, password: 'K6-StrongPass-1!', displayName: 'smoke-pub' });
|
|
|
|
// 2. register resend happy (new challenge issued). Respect the resend
|
|
// cooldown (etc/gateway.k6.yaml → Member.OTP.ResendCooldownSeconds=1) plus
|
|
// a small safety margin so we don't hit 29604000.
|
|
sleep(1.2);
|
|
resendRegister({ challengeId: reg.challenge_id });
|
|
|
|
// 3. login negative — wrong password against a non-existent user.
|
|
// Accepted outcomes:
|
|
// 401+28501000 → invalid credentials path (full OAuth client wired)
|
|
// 502+28802000 → zitadel request failed (default k6 env: no OAuth client,
|
|
// and modern ZITADEL v2 disables password grant anyway).
|
|
// Either outcome proves the endpoint is reachable + returns an error envelope.
|
|
const loginRes = post('/api/v1/auth/login', {
|
|
tenant_slug: cfg.tenantSlug,
|
|
email: 'no-such-user@k6.local',
|
|
password: 'wrongPassword1!',
|
|
});
|
|
checkErrorOneOf(loginRes, 'POST /auth/login (negative)', [
|
|
[401, 28501000],
|
|
[502, 28802000],
|
|
]);
|
|
|
|
// 4. token/refresh negative — bogus refresh token. Same dual-outcome reason.
|
|
const refreshRes = post('/api/v1/auth/token/refresh', { refresh_token: 'not-a-token' });
|
|
checkErrorOneOf(refreshRes, 'POST /auth/token/refresh (negative)', [
|
|
[401, 28501000],
|
|
[502, 28802000],
|
|
]);
|
|
|
|
// 5. register/social/start — requires Google IdP wired in ZITADEL.
|
|
// Accepted outcomes:
|
|
// 200+102000 → oauth_url returned (full Google IdP wired)
|
|
// 502+28802000 → zitadel request failed (default k6 env: no GoogleIdPID).
|
|
// We verify the endpoint accepts the request and returns either path.
|
|
const regSocialRes = post('/api/v1/auth/register/social/start', {
|
|
tenant_slug: cfg.tenantSlug,
|
|
invite_code: cfg.inviteCode,
|
|
provider: 'google',
|
|
accept_terms_version: '2025-01-01',
|
|
language: 'zh-TW',
|
|
redirect_uri: 'http://localhost:8888/api/v1/auth/register/social/callback',
|
|
});
|
|
checkErrorOneOf(regSocialRes, 'POST /auth/register/social/start', [
|
|
[200, 102000],
|
|
[502, 28802000],
|
|
]);
|
|
|
|
// 6. login/social/start — same dual-outcome reason.
|
|
const loginSocialRes = post('/api/v1/auth/login/social/start', {
|
|
tenant_slug: cfg.tenantSlug,
|
|
provider: 'google',
|
|
redirect_uri: 'http://localhost:8888/api/v1/auth/login/social/callback',
|
|
});
|
|
checkErrorOneOf(loginSocialRes, 'POST /auth/login/social/start', [
|
|
[200, 102000],
|
|
[502, 28802000],
|
|
]);
|
|
|
|
// 7. register/social/callback negative — invalid state
|
|
const cbReg = get('/api/v1/auth/register/social/callback?code=fake&state=invalid');
|
|
// 400 with 28101000 (oauth state invalid)
|
|
checkError(cbReg, 'GET /auth/register/social/callback (invalid state)', 400, 28101000);
|
|
|
|
// 8. login/social/callback negative — invalid state
|
|
const cbLogin = get('/api/v1/auth/login/social/callback?code=fake&state=invalid');
|
|
checkError(cbLogin, 'GET /auth/login/social/callback (invalid state)', 400, 28101000);
|
|
}
|