package ctbrec.ui.sites.cam4; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.Objects; import java.util.function.Consumer; import org.json.JSONArray; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.sites.cam4.Cam4; import ctbrec.ui.ExternalBrowser; import okhttp3.Cookie; import okhttp3.Cookie.Builder; import okhttp3.CookieJar; import okhttp3.HttpUrl; public class Cam4ElectronLoginDialog { private static final Logger LOG = LoggerFactory.getLogger(Cam4ElectronLoginDialog.class); public static final String DOMAIN = "cam4.com"; public static final String URL = Cam4.BASE_URI + "/login"; private CookieJar cookieJar; private ExternalBrowser browser; public Cam4ElectronLoginDialog(CookieJar cookieJar) throws IOException { this.cookieJar = cookieJar; browser = ExternalBrowser.getInstance(); try { JSONObject config = new JSONObject(); config.put("url", URL); config.put("w", 480); config.put("h", 640); JSONObject msg = new JSONObject(); msg.put("config", config); browser.run(msg, msgHandler); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IOException("Couldn't wait for login dialog", e); } finally { browser.close(); } } private Consumer msgHandler = line -> { if(!line.startsWith("{")) { LOG.error("Didn't received a JSON object {}", line); } else { JSONObject json = new JSONObject(line); if(json.has("url")) { String url = json.getString("url"); if(url.endsWith("/login")) { try { String username = Config.getInstance().getSettings().cam4Username; if (username != null && !username.trim().isEmpty()) { browser.executeJavaScript("document.querySelector('#loginPageForm input[name=\"username\"]').value = '" + username + "';"); } String password = Config.getInstance().getSettings().cam4Password; if (password != null && !password.trim().isEmpty()) { password = password.replace("'", "\\'"); browser.executeJavaScript("document.querySelector('#loginPageForm input[name=\"password\"]').value = '" + password + "';"); } browser.executeJavaScript("document.getElementById('footer').setAttribute('style', 'display:none');"); browser.executeJavaScript("document.getElementById('promptArea').setAttribute('style', 'display:none');"); browser.executeJavaScript("document.getElementById('content').setAttribute('style', 'padding: 0');"); browser.executeJavaScript("document.querySelector('div[class~=\"navbar\"]').setAttribute('style', 'display:none');"); } catch(Exception e) { LOG.warn("Couldn't auto fill username and password for Cam4", e); } } if(json.has("cookies")) { JSONArray cookiesFromBrowser = json.getJSONArray("cookies"); try { for (int i = 0; i < cookiesFromBrowser.length(); i++) { JSONObject cookie = cookiesFromBrowser.getJSONObject(i); if(cookie.getString("domain").contains("cam4")) { String domain = cookie.getString("domain"); if(domain.startsWith(".")) { domain = domain.substring(1); } Cookie c = createCookie(domain, cookie); cookieJar.saveFromResponse(HttpUrl.parse(url), Collections.singletonList(c)); c = createCookie("cam4.com", cookie); cookieJar.saveFromResponse(HttpUrl.parse(Cam4.BASE_URI), Collections.singletonList(c)); } } if (Objects.equals(new URL(url).getPath(), "/")) { closeBrowser(); } } catch (MalformedURLException e) { LOG.error("Couldn't parse new url {}", url, e); } } } } }; private Cookie createCookie(String domain, JSONObject cookie) { Builder b = new Cookie.Builder() .path(cookie.getString("path")) .domain(domain) .name(cookie.getString("name")) .value(cookie.getString("value")) .expiresAt((long) cookie.optDouble("expirationDate")); if(cookie.optBoolean("hostOnly")) { b.hostOnlyDomain(domain); } if(cookie.optBoolean("httpOnly")) { b.httpOnly(); } if(cookie.optBoolean("secure")) { b.secure(); } return b.build(); } private void closeBrowser() { try { browser.close(); } catch(IOException e) { LOG.error("Couldn't send close request to browser", e); } } }