SC login v3 API

This commit is contained in:
jafea7 2025-04-26 23:01:32 +10:00 committed by Jafea7
parent 5b34aa3b34
commit 4381375cc9
1 changed files with 151 additions and 71 deletions

View File

@ -4,6 +4,7 @@ import ctbrec.Config;
import ctbrec.StringUtil;
import ctbrec.io.HttpClient;
import ctbrec.io.HttpException;
// import ctbrec.sites.stripchat.Stripchat;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
@ -12,13 +13,17 @@ import org.json.JSONObject;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import static ctbrec.io.HttpConstants.*;
import static java.nio.charset.StandardCharsets.UTF_8;
@Slf4j
public class StripchatHttpClient extends HttpClient {
Stripchat stripchatInstance = new Stripchat();
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private long userId;
@ -32,16 +37,17 @@ public class StripchatHttpClient extends HttpClient {
@Getter
private String jwtToken;
private Instant jwtTokenExp;
public StripchatHttpClient(Config config) {
super("stripchat", config);
}
@Override
public boolean login() throws IOException {
if (loggedIn) {
if (csrfToken == null) {
loadCsrfToken();
}
getCsrfToken(); // Always load CSRF token (as in v5.0.24)
if (loggedIn && isJwtTokenValid()) { // Ensure JWT is valid as in v5.0.24
return true;
}
@ -49,24 +55,22 @@ public class StripchatHttpClient extends HttpClient {
if (checkLoginSuccess()) {
loggedIn = true;
log.debug("Logged in with cookies");
// Check if CSRF token needs to be loaded after logging in via cookies
if (csrfToken == null) {
loadCsrfToken();
}
return true;
}
if (csrfToken == null) {
loadCsrfToken();
}
// Proceed to the login HTTP request if not already logged in
String url = Stripchat.getBaseUri() + "/api/front/auth/login";
JSONObject requestParams = new JSONObject();
requestParams.put("loginOrEmail", config.getSettings().stripchatUsername);
requestParams.put("password", config.getSettings().stripchatPassword);
requestParams.put("remember", true);
requestParams.put("csrfToken", csrfToken);
requestParams.put("csrfTimestamp", csrfTimestamp);
requestParams.put("csrfNotifyTimestamp", csrfNotifyTimestamp);
JSONObject requestParams = new JSONObject()
.put("loginOrEmail", config.getSettings().stripchatUsername)
.put("password", config.getSettings().stripchatPassword)
.put("remember", true)
.put("csrfToken", csrfToken)
.put("csrfTimestamp", csrfTimestamp)
.put("csrfNotifyTimestamp", csrfNotifyTimestamp);
RequestBody body = RequestBody.Companion.create(requestParams.toString(), JSON);
Request request = new Request.Builder()
.url(url)
@ -77,40 +81,49 @@ public class StripchatHttpClient extends HttpClient {
.header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
.post(body)
.build();
try (Response response = execute(request)) {
if (response.isSuccessful()) {
JSONObject resp = new JSONObject(response.body().string());
if (resp.has("user")) {
JSONObject user = resp.getJSONObject("user");
userId = user.optLong("id");
return true;
return true; // Successful login
} else {
return false;
return false; // No user found
}
} else {
log.info("Auto-Login failed: {} {} {}", response.code(), response.message(), url);
return false;
return false; // Request failed
}
}
}
private void loadCsrfToken() throws IOException {
String url = Stripchat.getBaseUri() + "/api/front/v2/config/data?requestPath=%2F&timezoneOffset=0";
Request request = new Request.Builder()
.url(url)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
.header(USER_AGENT, config.getSettings().httpUserAgent)
.header(ORIGIN, Stripchat.getBaseUri())
.header(REFERER, Stripchat.getBaseUri())
.header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
.build();
csrfToken = "";
csrfTimestamp = "";
csrfNotifyTimestamp = "";
String url = Stripchat.getBaseUri() + "/api/front/v3/config/initial?requestPath=%2F&timezoneOffset=0&disableClient=0&uniq=" + stripchatInstance.getUniq();
Request request = buildJsonGetRequest(url);
try (Response response = execute(request)) {
if (response.isSuccessful()) {
JSONObject resp = new JSONObject(response.body().string());
JSONObject data = resp.getJSONObject("data");
csrfToken = data.optString("csrfToken");
csrfTimestamp = data.optString("csrfTimestamp");
csrfNotifyTimestamp = data.optString("csrfNotifyTimestamp");
JSONObject initial = resp.optJSONObject("initial");
if (initial != null) {
JSONObject client = initial.optJSONObject("client");
if (client != null) {
csrfToken = client.optString("csrfToken");
csrfTimestamp = client.optString("csrfTimestamp");
csrfNotifyTimestamp = client.optString("csrfNotifyTimestamp");
log.debug("Stripchat CSRF token (v3): {} [{}]", csrfToken, csrfNotifyTimestamp);
}
}
if (csrfToken.isBlank()) {
log.debug("Stripchat CSRF token not found");
}
} else {
throw new HttpException(response.code(), response.message());
}
@ -118,51 +131,53 @@ public class StripchatHttpClient extends HttpClient {
}
private void loadJwtToken() throws IOException {
String url = Stripchat.getBaseUri() + "/api/front/v2/config?requestPath=%2F&timezoneOffset=0";
Request request = new Request.Builder()
.url(url)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
.header(USER_AGENT, config.getSettings().httpUserAgent)
.header(ORIGIN, Stripchat.getBaseUri())
.header(REFERER, Stripchat.getBaseUri())
.header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
.build();
jwtToken = "";
String url = Stripchat.getBaseUri() + "/api/front/v3/config/dynamic?uniq=" + stripchatInstance.getUniq();
Request request = buildJsonGetRequest(url);
try (Response response = execute(request)) {
if (response.isSuccessful()) {
JSONObject resp = new JSONObject(response.body().string());
JSONObject config = resp.getJSONObject("config");
jwtToken = config.optString("jwtToken");
JSONObject dynamic = resp.optJSONObject("dynamic");
if (dynamic != null) {
jwtToken = dynamic.optString("jwtToken");
}
if (jwtToken != null && !jwtToken.isBlank()) {
String[] parts = jwtToken.split("\\.");
if (parts.length > 1) {
String payload = new String(Base64.getDecoder().decode(parts[1]), StandardCharsets.UTF_8);
JSONObject body = new JSONObject(payload);
jwtTokenExp = Instant.ofEpochSecond(body.optLong("exp"));
}
log.debug("Stripchat JWT token (v3): {} [{}]", jwtToken, jwtTokenExp);
} else {
log.debug("Stripchat JWT token not found");
}
} else {
throw new HttpException(response.code(), response.message());
}
}
}
/**
* check, if the login worked
*/
public boolean checkLoginSuccess() throws IOException {
try {
loadJwtToken();
getJwtToken();
getCsrfToken();
} catch (Exception e) {
log.info("Login check returned unsuccessful: {}", e.getLocalizedMessage());
jwtToken = "";
csrfToken = "";
return false;
}
return StringUtil.isNotBlank(jwtToken);
return StringUtil.isNotBlank(jwtToken) && StringUtil.isNotBlank(csrfToken);
}
public long getUserId() throws JSONException, IOException {
if (userId == 0) {
if (userId == 0L) {
String url = Stripchat.getBaseUri() + "/api/front/users/username/" + config.getSettings().stripchatUsername;
Request request = new Request.Builder()
.url(url)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
.header(USER_AGENT, config.getSettings().httpUserAgent)
.header(ORIGIN, Stripchat.getBaseUri())
.header(REFERER, Stripchat.getBaseUri())
.header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
.build();
Request request = buildJsonGetRequest(url);
try (Response response = execute(request)) {
if (response.isSuccessful()) {
JSONObject resp = new JSONObject(response.body().string());
@ -181,9 +196,74 @@ public class StripchatHttpClient extends HttpClient {
Cookie cookie = getCookieJar().getCookie(HttpUrl.parse(Stripchat.getBaseUri()), "baseAmpl");
String json = URLDecoder.decode(cookie.value(), UTF_8);
JSONObject ampl = new JSONObject(json);
ampl.put("ep", new JSONObject());
return ampl;
} catch (Exception ex) {
return new JSONObject();
}
}
public String getCsrfNotifyTimestamp() {
return csrfNotifyTimestamp;
}
public String getCsrfTimestamp() {
return csrfTimestamp;
}
public String getCsrfToken() {
try {
if (!isTokenValid()) {
loadCsrfToken(); // Uses v3 API load
}
} catch (Exception e) {
log.debug("Invalid CSRF Token {}: {}", csrfToken, e.getMessage());
csrfToken = ""; // Reset token on failure
}
return csrfToken;
}
public String getJwtToken() {
try {
if (!isJwtTokenValid()) {
loadJwtToken(); // Uses v3 API load
}
} catch (Exception e) {
log.debug("Invalid JWT Token {}: {}", jwtToken, e.getMessage());
jwtToken = ""; // Reset token on failure
}
return jwtToken;
}
private boolean isJwtTokenValid() {
if (StringUtil.isBlank(jwtToken) || jwtTokenExp == null) {
return false;
}
return jwtTokenExp.isAfter(Instant.now().minus(3L, ChronoUnit.HOURS));
}
private boolean isTokenValid() {
if (StringUtil.isBlank(csrfToken) || StringUtil.isBlank(csrfTimestamp) || StringUtil.isBlank(csrfNotifyTimestamp)) {
return false;
}
try {
Instant notifyTime = Instant.parse(csrfNotifyTimestamp);
return notifyTime.isAfter(Instant.now().minus(3L, ChronoUnit.HOURS));
}
catch (Exception e) {
return false;
}
}
private Request buildJsonGetRequest(String url) {
return new Request.Builder()
.url(url)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
.header(USER_AGENT, config.getSettings().httpUserAgent)
.header(ORIGIN, Stripchat.getBaseUri())
.header(REFERER, Stripchat.getBaseUri())
.header(CONTENT_TYPE, MIMETYPE_APPLICATION_JSON)
.build();
}
}