autoreg-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok60915d52e8425
2026-10-20 02:16:32 +03:00
commit f58eafeb48
565 changed files with 60064 additions and 0 deletions

View File

@@ -0,0 +1,211 @@
# Kamatera Free Trial — Registration & Billing API
## Overview
Kamatera offers a 30-day free trial ($100 cloud credit) with payment card required. The registration and billing flow is entirely API-driven through a WordPress-based backend.
## Registration
### Endpoint (WordPress AJAX)
```
POST https://www.kamatera.com/wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded
```
### jQuery Serialization Format
The form uses jQuery's `$.ajax` with nested objects. Key format: `data_options[field]=value`
```
action=cwm_api_action
data_options[cases]=cwml
data_options[email]=...@domain.com
data_options[password]=...
data_options[orgUrl]=https://www.kamatera.com/free-trial/
data_options[formButtonText]=Create free account
data_options[submitText]=Create free account
data_options[headerText]=
```
### Email Validation
- Client-side regex: `/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/`
- **`+` aliases NOT allowed** (Gmail `+suffix` fails `\w` check)
- Use plain emails or disposable email domains
### Password Requirements
- At least 1 lowercase
- At least 1 uppercase
- At least 1 number
- At least 8 characters
- Less than 28 characters
### Response
```json
{
"status": 0, // 0 = success, 13 = blocked/captcha fail
"token": "...",
"existing": false, // true if account already exists
"url": "https://console.kamatera.com/al.php?t=...",
"validationToken": "...",
"impactid": "kt-..."
}
```
Status 13 with `url: null` = blocked (likely reCAPTCHA v3 score too low, or IP flagged).
## Email Verification
Verification email comes from `support@kamatera.com` with subject "Confirm your Kamatera cloud account". Contains a link:
```
https://console.kamatera.com/rd.php?t=...&e=...&p=emailValidation&h=...
```
Click the link → redirects to `validateSuccessful?email=...` → account verified.
## Disposable Email
**mail.tm** works reliably:
```python
# 1. Get domain
r = requests.get("https://api.mail.tm/domains")
domain = r.json()["hydra:member"][0]["domain"]
# 2. Create account
r = requests.post("https://api.mail.tm/accounts", json={
"address": f"{username}@{domain}",
"password": "password"
})
# 3. Get token
r = requests.post("https://api.mail.tm/token", json={
"address": email, "password": "password"
})
token = [REDACTED])["token"]
# 4. Read messages
r = requests.get("https://api.mail.tm/messages",
headers={"Authorization": f"Bearer {token}"})
```
**GuerrillaMail** works but Kamatera emails may not arrive to `.guerrillamailblock.com` — use mail.tm instead.
## Console API
### Base URL & Auth
```
Base: https://console.kamatera.com/svc/
Headers:
Content-Type: application/json
Accept: application/json
api-version: latest
token: <CSRF_TOKEN>
```
### CSRF Token
Get from `/csrf` endpoint:
```python
r = requests.get("https://console.kamatera.com/csrf")
csrf = re.search(r'CSRF_TOKEN",\s*"([^"]+)"', r.text).group(1)
```
The `/csrf` page returns HTML that sets `sessionStorage.setItem("CSRF_TOKEN", "...")`. The token is embedded in the HTML as a script tag.
### Login Flow (with 2FA)
```
1. POST /svc/login {"email", "password"}
→ {"email": "...", "mediateToken": "..."}
2. POST /svc/sendtfa {"email", "mediateToken"} (header: token=<csrf>)
→ triggers email with 6-digit code
3. Check mail.tm for code in subject "Kamatera Cloud Platform: 2-Step Verification"
4. POST /svc/logintfa {"email", "code", "rememberBrowser": true, "mediateToken"}
→ 200 = logged in, session cookie set
→ 400 + code 51 = "Invalid code" (code expired or wrong)
```
### TFA Code Pitfalls
- Codes expire quickly (~2-5 minutes)
- `sendtfa` may return 200 but NOT send a new email if one was already sent recently
- Delete old emails from mail.tm before calling `sendtfa` to avoid picking up stale codes
- The 2FA email body contains the code in format: `Your access code ... is: XXXXXX`
- Filter out false positives: `1999` and `2026` are in the email footer, not the code
### Billing Profile API
```
PUT /svc/billing/profile (header: token=<csrf>)
```
### Billing Profile Fields (Discovered via Progressive 400 Errors)
The API validates fields in sequence. Each fix reveals the next missing field:
| Error Code | Message | Required Fix |
|-----------|---------|-------------|
| 122 | invalid invoice name | Add `invoiceName` |
| 105 | invalid first name | Add `firstName` |
| 107 | invalid country | Fix `country` format |
| 110 | invalid city | Add `city` |
| 112 | invalid zip code | Use `postalCode` (NOT `zipCode` or `zip`) |
| 109 | invalid phone | Add `phone` |
| 21 | generic error | Card rejected by payment processor |
### Working Billing Payload (Passes All Validation)
```json
{
"firstName": "Alex",
"lastName": "Morgan",
"country": "US",
"city": "New York",
"address": "123 Broadway",
"state": "NY",
"postalCode": "10001",
"phone": "2125550100",
"invoiceName": "Alex Morgan",
"paymentType": 0,
"cardNumber": "4874100085748500",
"cardExpiry": "05/2030",
"cardCvv": "617"
}
```
### Error Code 21 (Card Rejected)
After all field validation passes, error 21 means the payment processor rejected the card. This is NOT a field format issue. Possible causes:
- Card blocked/stolen
- Insufficient funds for $1 authorization hold
- 3D Secure required but not supported
- Region mismatch (card issuing country ≠ billing country)
- Card expired (check BIN + expiry date format)
### Card Expiry Formats Tried
- `cardExpiry: "05/2030"` — works (passes to processor)
- `cardExpiry: "05/30"` — works (passes to processor)
- Separate `expMonth`/`expYear` fields — also pass validation
All formats pass field validation — the rejection is at the payment processor level.
## Browser-Based API Calls
When the React SPA is unresponsive (clicks don't navigate), use `fetch()` from browser console with the session's CSRF token:
[REDACTED]
fetch('/svc/billing/profile', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'api-version': 'latest',
'token': sessionStorage.getItem('CSRF_TOKEN')
},
body: JSON.stringify({...})
}).then(r => r.json()).then(d => console.log(JSON.stringify(d)))
```
This bypasses the broken React navigation and uses the browser's authenticated session directly.
## Key Pitfalls
1. **Email `+` aliases fail client-side validation** — use plain email or disposable domain
2. **`sendtfa` doesn't always send** — delete old emails before calling, codes may have cooldown
3. **React SPA navigation broken in headless** — use direct `fetch()` from console
4. **Field names are specific**: `postalCode` not `zipCode`, `invoiceName` required, `firstName`/`lastName` not `name`
5. **Country format**: `"US"` (2-letter ISO) works, `"USA"` fails
6. **Card validation is sequential** — fix errors one at a time, each reveals the next