package recon

import "github.com/Armur-Ai/Pentest-Swarm-AI/internal/pipeline"

// vapiProfile is the API surface of vAPI (roottusk/vapi), a Laravel lab built
// to walk the OWASP API Security Top 10 one "exercise" at a time (api1..api10,
// plus jwt / stickynotes). Every route is a bare JSON endpoint mounted under the
// /vapi prefix (Route::prefix('vapi') in RouteServiceProvider), so without this
// profile the exploit agent never sees the surface where vAPI's planted flaws
// live.
//
// Routes verbatim from vapi/routes/api.php (default branch). Each exercise maps
// to one OWASP API risk; the Notes tell the exploit planner which flaw lives on
// each route and how to prove it. No chains are included (not yet exercised
// against a live instance), so response shapes — JWT field names, id formats —
// must be confirmed from a live response before wiring --capture paths.
var vapiProfile = apiProfile{
	name: "vapi",
	// Signatures: two GET routes that exist on vAPI (non-404, even unauthenticated
	// they answer 200/401/403) and 404 on an unrelated app. api5/users (list) and
	// api7/user/login (vAPI defines login as GET here) are both always-mounted.
	signatures: []signatureRoute{
		{method: "GET", path: "/vapi/api5/users"},
		{method: "GET", path: "/vapi/api7/user/login"},
	},
	build: func(base string) []pipeline.EndpointRecord {
		v := base + "/vapi"
		return []pipeline.EndpointRecord{
			// --- API1: Broken Object Level Authorization (BOLA) ---
			{
				URL:    v + "/api1/user",
				Method: "POST",
				Notes: "API1 (BOLA) registration. Body (JSON): " +
					`{"name":"atk_{{nonce}}","email":"atk_{{nonce}}@example.com","password":"Attacker@123"}. ` +
					"Create your own account, note the returned id, then attack the {id} routes below.",
			},
			{
				URL:         v + "/api1/user/{{victim_id}}",
				Method:      "GET",
				Interesting: true,
				Parameters:  []string{"id"},
				Notes: "API1 BOLA (flagship): read another user's record by numeric id with your own token. " +
					"Harvest a victim id by registering two accounts (ids are sequential) or from any list route. " +
					"A 200 returning a record whose id/email is not the caller's proves broken object-level " +
					"authorization. This is the canonical --verify BOLA case: differential attack id vs a " +
					"well-formed non-existent control id.",
			},
			{
				URL:         v + "/api1/user/{{victim_id}}",
				Method:      "PUT",
				Interesting: true,
				Parameters:  []string{"id"},
				Notes: "API1 BOLA write: update another user's record by id with your own token. Body (JSON): " +
					`{"name":"pwned_{{nonce}}"}. A 200 mutating a record you do not own proves an unauthorized ` +
					"cross-user write.",
			},
			// --- API2: Broken Authentication ---
			{
				URL:    v + "/api2/user/login",
				Method: "POST",
				Notes: "API2 (Broken Authentication) login. Body (JSON): " +
					`{"email":"atk_{{nonce}}@example.com","password":"Attacker@123"}. ` +
					"Capture the returned token (confirm the exact field from a live response) and reuse it as " +
					"Authorization: Bearer {{token}}. Probe for weak/guessable tokens and missing expiry.",
			},
			{
				URL:         v + "/api2/user/details",
				Method:      "GET",
				Interesting: true,
				Notes: "API2: returns the authenticated user's details. Test with a forged/guessed/tampered " +
					"token — a 200 with another user's details on a manipulated token proves broken auth.",
			},
			// --- API3: Excessive Data Exposure ---
			{
				URL:    v + "/api3/user/login",
				Method: "POST",
				Notes: "API3 login. Body (JSON): {\"email\":\"...\",\"password\":\"...\"}. Register first at " +
					"POST /vapi/api3/user with the same body shape plus a name.",
			},
			{
				URL:         v + "/api3/comment",
				Method:      "GET",
				Interesting: true,
				Notes: "API3 (Excessive Data Exposure): GET comments returns more fields than the UI needs " +
					"(e.g. internal user data attached to each comment). A 200 whose body carries fields beyond " +
					"the comment text/author — emails, ids, tokens — proves the finding. POST /vapi/api3/comment " +
					"creates one.",
			},
			// --- API4: Lack of Resources & Rate Limiting (OTP brute force) ---
			{
				URL:    v + "/api4/login",
				Method: "POST",
				Notes:  "API4 step 1: login to trigger an OTP. Body (JSON): {\"email\":\"...\",\"password\":\"...\"}.",
			},
			{
				URL:         v + "/api4/otp/verify",
				Method:      "POST",
				Interesting: true,
				Notes: "API4 (Lack of Resources & Rate Limiting): OTP verification with NO rate limit. Body " +
					"(JSON): {\"otp\":\"0000\",\"email\":\"...\"}. Brute-force the numeric OTP (small space) with " +
					"repeated requests — success without any throttling/lockout proves the flaw. Use a bounded " +
					"loop, not an unbounded flood.",
			},
			// --- API5: Broken Function Level Authorization (BFLA) ---
			{
				URL:         v + "/api5/users",
				Method:      "GET",
				Interesting: true,
				Notes: "API5 (BFLA): a privileged 'list all users' function reachable by a non-privileged " +
					"caller. A 200 dumping all users for an ordinary (or no) token proves broken function-level " +
					"authorization. POST /vapi/api5/user registers.",
			},
			{
				URL:         v + "/api5/user/{{victim_id}}",
				Method:      "GET",
				Interesting: true,
				Parameters:  []string{"id"},
				Notes: "API5 BFLA/BOLA: fetch a specific user by id through the admin-style function with a " +
					"low-privilege token. A cross-user 200 proves the finding.",
			},
			// --- API6: Mass Assignment ---
			{
				URL:    v + "/api6/user",
				Method: "POST",
				Notes: "API6 (Mass Assignment) registration. Baseline body (JSON): " +
					`{"name":"atk_{{nonce}}","email":"atk_{{nonce}}@example.com","password":"Attacker@123"}. ` +
					"Then repeat with an extra privileged field the API should ignore — e.g. add " +
					`"credit":1000000 or "isAdmin":true / "role":"admin" — and confirm via GET /vapi/api6/user/me ` +
					"that the created account carries the smuggled value. This is the canonical --verify " +
					"mass-assignment case (attack body with the field vs control body without it).",
			},
			{
				URL:         v + "/api6/user/me",
				Method:      "GET",
				Interesting: true,
				Notes: "API6: returns the caller's own record — use it to confirm a mass-assigned privileged " +
					"field took effect (the field is present/elevated though it was never grantable via normal " +
					"flow).",
			},
			// --- API7: Security Misconfiguration ---
			{
				URL:         v + "/api7/user/login",
				Method:      "GET",
				Interesting: true,
				Notes: "API7 (Security Misconfiguration): vAPI exposes login as GET (credentials in the URL/query) " +
					"and leaks an API key route. Register at POST /vapi/api7/user, then GET /vapi/api7/user/key to " +
					"retrieve a key that should not be exposed — a 200 returning a secret key proves the misconfig.",
			},
			{
				URL:         v + "/api7/user/key",
				Method:      "GET",
				Interesting: true,
				Notes: "API7: fetch the user's API key. Exposed over a misconfigured route; a 200 with a key " +
					"value is the finding.",
			},
			// --- API8: Injection ---
			{
				URL:         v + "/api8/user/login",
				Method:      "POST",
				Interesting: true,
				Notes: "API8 (Injection): the login handler is injectable. Body (JSON): " +
					`{"email":"...","password":"..."}. Probe the email/password fields for SQL injection (e.g. ` +
					"a classic ' OR '1'='1 style auth bypass, or sqlmap against the JSON parameter) — an auth " +
					"bypass or error-based leak proves it. GET /vapi/api8/user/secret returns a secret once " +
					"authenticated.",
			},
			// --- API9: Improper Assets Management ---
			{
				URL:         v + "/api9/v1/user/login",
				Method:      "POST",
				Interesting: true,
				Notes: "API9 (Improper Assets Management): an OLD, unthrottled v1 of the login endpoint is left " +
					"exposed alongside the hardened v2 (/vapi/api9/v2/user/login, throttle:5,1). Reaching v1 and " +
					"brute-forcing it where v2 is rate-limited proves a deprecated/undocumented version is still " +
					"live. Body (JSON): {\"email\":\"...\",\"password\":\"...\"}.",
			},
			// --- JustWeakToken: weak JWT ---
			{
				URL:         v + "/jwt/user",
				Method:      "GET",
				Interesting: true,
				Notes: "JustWeakToken: register at POST /vapi/jwt/user, then this GET returns data gated by a " +
					"JWT signed with a weak/guessable secret. Crack the secret (e.g. jwt_tool/hashcat against the " +
					"token) and forge an elevated token — acceptance of a re-signed token proves the weak-secret " +
					"flaw.",
			},
		}
	},
	chains: nil,
}
