|
|
@@ -7,11 +7,14 @@ import cn.hutool.http.HttpRequest;
|
|
|
import cn.hutool.http.HttpResponse;
|
|
|
import cn.hutool.http.HttpUtil;
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.cyksj.common.constant.Constant;
|
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
|
import com.cyksj.common.util.Jsons;
|
|
|
import com.cyksj.common.util.StringUtil;
|
|
|
import com.cyksj.common.util.TicketCodeCommonUtil;
|
|
|
+import com.cyksj.mapper.sys.SysEmailMapper;
|
|
|
+import com.cyksj.model.entity.SysEmail;
|
|
|
import com.cyksj.model.response.AdobeEmailResp;
|
|
|
import com.cyksj.model.response.DisneyCodeResp;
|
|
|
import com.cyksj.service.mail.CommonMailService;
|
|
|
@@ -43,10 +46,18 @@ public class CommonMailServiceImpl implements CommonMailService {
|
|
|
|
|
|
private final YhMailService yhMailService;
|
|
|
|
|
|
+ private final SysEmailMapper sysEmailMapper;
|
|
|
+
|
|
|
//GPT修改密码匹配
|
|
|
private final static String GPT_RESET_PWD_LINK_REGEX = "https://auth0.openai.com/u/reset-verify";
|
|
|
@Override
|
|
|
public String getTicketMailCode(Long goodsId, String account, String relateEmail, String emailPwd, Date emailCreatedTime, Integer type, Integer linkType, Boolean isReturnDeviceUrl) throws Exception {
|
|
|
+ if (StrUtil.isEmpty(emailPwd)) {
|
|
|
+ SysEmail sysEmail = sysEmailMapper.selectOne(Wrappers.lambdaQuery(SysEmail.class).eq(SysEmail::getEmail, account).last("limit 1"));
|
|
|
+ if (sysEmail != null) {
|
|
|
+ emailPwd = sysEmail.getPassword();
|
|
|
+ }
|
|
|
+ }
|
|
|
if (StrUtil.isEmpty(relateEmail)) {
|
|
|
//25年的GPT账号获取验证码 特殊处理
|
|
|
//获取失败走下一步
|
|
|
@@ -107,14 +118,18 @@ public class CommonMailServiceImpl implements CommonMailService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //Netflix get verify code
|
|
|
- if (Constant.NETFLIX_GID.equals(goodsId) && linkType == null && (type == null || type == 1) && StrUtil.isNotBlank(emailPwd)) {
|
|
|
+ //Netflix get verify code or household device link
|
|
|
+ if (Constant.NETFLIX_GID.equals(goodsId) && StrUtil.isNotBlank(emailPwd)
|
|
|
+ && ((linkType == null && (type == null || type == 1))
|
|
|
+ || (linkType == 1 && Boolean.TRUE.equals(isReturnDeviceUrl)))) {
|
|
|
try {
|
|
|
String url = "https://ms.lqqq.cc/web/" + account + "----" + emailPwd;
|
|
|
HttpRequest post = HttpUtil.createGet(url).timeout(Constant.CONNECT_MILLISECONDS);
|
|
|
HttpResponse execute = post.execute();
|
|
|
String body = execute.body();
|
|
|
- String code = getNetflixVerifyCodeByLqqqMail(account, emailPwd, body);
|
|
|
+ String code = linkType != null && linkType == 1
|
|
|
+ ? getNetflixHouseholdDeviceUrlByLqqqMail(account, body)
|
|
|
+ : getNetflixVerifyCodeByLqqqMail(account, body);
|
|
|
if (StrUtil.isNotBlank(code)) {
|
|
|
return code;
|
|
|
}
|
|
|
@@ -126,37 +141,41 @@ public class CommonMailServiceImpl implements CommonMailService {
|
|
|
String checkEmail = StrUtil.isNotEmpty(relateEmail) ? relateEmail : account;
|
|
|
//关联邮箱
|
|
|
if (cuiQiuMailService.isCuiQiuEmail(checkEmail)) {
|
|
|
- return cuiQiuMailService.getVerifyCode(account, relateEmail, goodsId, type, linkType, false);
|
|
|
+ return cuiQiuMailService.getVerifyCode(account, relateEmail, goodsId, type, linkType, Boolean.TRUE.equals(isReturnDeviceUrl));
|
|
|
}
|
|
|
//是否是 mail lu邮箱
|
|
|
if (mailLuService.isMailLuEmail(checkEmail)) {
|
|
|
- return mailLuService.getVerifyCode(account, relateEmail, goodsId, type, linkType, false);
|
|
|
+ return mailLuService.getVerifyCode(account, relateEmail, goodsId, type, linkType, Boolean.TRUE.equals(isReturnDeviceUrl));
|
|
|
}
|
|
|
//银河域名邮件
|
|
|
- return yhMailService.getVerifyCode(account, relateEmail, goodsId, type, linkType, false);
|
|
|
+ return yhMailService.getVerifyCode(account, relateEmail, goodsId, type, linkType, Boolean.TRUE.equals(isReturnDeviceUrl));
|
|
|
}
|
|
|
|
|
|
- private String getNetflixVerifyCodeByLqqqMail(String account, String emailPwd, String body) {
|
|
|
+ private String getNetflixVerifyCodeByLqqqMail(String account, String body) {
|
|
|
if (StrUtil.isBlank(body)) {
|
|
|
return StrUtil.EMPTY;
|
|
|
}
|
|
|
if (!body.contains("/show_email/")) {
|
|
|
return getNetflixVerifyCode(body);
|
|
|
}
|
|
|
- Matcher matcher = Pattern.compile("href=\"([^\"]*/show_email/[^\"]+)\"", Pattern.CASE_INSENSITIVE).matcher(body);
|
|
|
+ Matcher matcher = Pattern.compile("<a\\b[^>]*href=\"([^\"]*/show_email/[^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE).matcher(body);
|
|
|
while (matcher.find()) {
|
|
|
String href = matcher.group(1);
|
|
|
- int start = Math.max(0, matcher.start() - 800);
|
|
|
- int end = Math.min(body.length(), matcher.end() + 200);
|
|
|
- String emailItem = body.substring(start, end);
|
|
|
+ String emailItem = getMailListItemHtml(body, matcher.start());
|
|
|
if (!emailItem.contains(Constant.NETFLIX) || !isNetflixLoginCodeMail(emailItem)) {
|
|
|
continue;
|
|
|
}
|
|
|
+ String code = getNetflixVerifyCodeFromListItem(emailItem);
|
|
|
+ if (StrUtil.isNotBlank(code)) {
|
|
|
+ log.info("Netflix {} get verify code from lqqq mail list: {}", account, code);
|
|
|
+ return code;
|
|
|
+ }
|
|
|
try {
|
|
|
String detailUrl = href.startsWith("http") ? href : "https://ms.lqqq.cc" + href;
|
|
|
HttpResponse detailResp = HttpUtil.createGet(detailUrl).timeout(Constant.CONNECT_MILLISECONDS).execute();
|
|
|
- String code = getNetflixVerifyCode(detailResp.body());
|
|
|
+ code = getNetflixVerifyCode(detailResp.body());
|
|
|
if (StrUtil.isNotBlank(code)) {
|
|
|
+ log.info("Netflix {} get verify code from lqqq mail detail: {}", account, code);
|
|
|
return code;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
@@ -166,6 +185,106 @@ public class CommonMailServiceImpl implements CommonMailService {
|
|
|
return StrUtil.EMPTY;
|
|
|
}
|
|
|
|
|
|
+ private String getNetflixHouseholdDeviceUrlByLqqqMail(String account, String body) {
|
|
|
+ if (StrUtil.isBlank(body)) {
|
|
|
+ return StrUtil.EMPTY;
|
|
|
+ }
|
|
|
+ String url = getNetflixHouseholdDeviceUrl(body);
|
|
|
+ if (StrUtil.isNotBlank(url)) {
|
|
|
+ return url;
|
|
|
+ }
|
|
|
+ Matcher matcher = Pattern.compile("<a\\b[^>]*href=\"([^\"]*/show_email/[^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE).matcher(body);
|
|
|
+ while (matcher.find()) {
|
|
|
+ String emailItem = getMailListItemHtml(body, matcher.start());
|
|
|
+ if (!isNetflixHouseholdDeviceMail(emailItem)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ String href = decodeHtmlUrl(matcher.group(1));
|
|
|
+ String detailUrl = href.startsWith("http") ? href : "https://ms.lqqq.cc" + href;
|
|
|
+ HttpResponse detailResp = HttpUtil.createGet(detailUrl).timeout(Constant.CONNECT_MILLISECONDS).execute();
|
|
|
+ url = getNetflixHouseholdDeviceUrl(detailResp.body());
|
|
|
+ if (StrUtil.isNotBlank(url)) {
|
|
|
+ log.info("Netflix {} get household device url from lqqq mail detail", account);
|
|
|
+ return url;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Netflix {} read household device mail failed: {}", account, StringUtil.getErrorMsg(e));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return StrUtil.EMPTY;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isNetflixHouseholdDeviceMail(String body) {
|
|
|
+ if (StrUtil.isBlank(body) || !body.toLowerCase().contains("netflix")) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ String text = cleanMailHtml(body).toLowerCase();
|
|
|
+ return text.contains("update netflix household")
|
|
|
+ || text.contains("netflix household device")
|
|
|
+ || text.contains("update-primary-location")
|
|
|
+ || text.contains("\u66f4\u65b0 netflix \u540c\u6237\u8bbe\u5907")
|
|
|
+ || text.contains("\u66f4\u65b0 netflix \u540c\u6236\u88dd\u7f6e");
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getNetflixHouseholdDeviceUrl(String body) {
|
|
|
+ if (StrUtil.isBlank(body)) {
|
|
|
+ return StrUtil.EMPTY;
|
|
|
+ }
|
|
|
+ Matcher matcher = Pattern.compile("https://www\\.netflix\\.com/account/update-primary-location[^\\s\\\"'<>]*", Pattern.CASE_INSENSITIVE).matcher(body);
|
|
|
+ if (matcher.find()) {
|
|
|
+ return decodeHtmlUrl(matcher.group());
|
|
|
+ }
|
|
|
+ return StrUtil.EMPTY;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String decodeHtmlUrl(String url) {
|
|
|
+ return StrUtil.blankToDefault(url, StrUtil.EMPTY)
|
|
|
+ .replace("&", "&")
|
|
|
+ .replace("&", "&")
|
|
|
+ .replace("&", "&");
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getMailListItemHtml(String body, int hrefStart) {
|
|
|
+ int cardStart = body.lastIndexOf("<article", hrefStart);
|
|
|
+ if (cardStart < 0) {
|
|
|
+ cardStart = body.lastIndexOf("<div class=\"email-card", hrefStart);
|
|
|
+ }
|
|
|
+ if (cardStart < 0) {
|
|
|
+ cardStart = Math.max(0, hrefStart - 1200);
|
|
|
+ }
|
|
|
+ int nextCardStart = body.indexOf("<article", hrefStart + 1);
|
|
|
+ int legacyNextCardStart = body.indexOf("<div class=\"email-card", hrefStart + 1);
|
|
|
+ int cardEnd = body.length();
|
|
|
+ if (nextCardStart > 0) {
|
|
|
+ cardEnd = Math.min(cardEnd, nextCardStart);
|
|
|
+ }
|
|
|
+ if (legacyNextCardStart > 0) {
|
|
|
+ cardEnd = Math.min(cardEnd, legacyNextCardStart);
|
|
|
+ }
|
|
|
+ cardEnd = Math.min(cardEnd, hrefStart + 1200);
|
|
|
+ return body.substring(cardStart, cardEnd);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getNetflixVerifyCodeFromListItem(String emailItem) {
|
|
|
+ String text = cleanMailHtml(emailItem);
|
|
|
+ String[] startStrs = new String[]{
|
|
|
+ "Enter this code to sign in",
|
|
|
+ "Informe este c\u00f3digo para entrar",
|
|
|
+ "\u8f38\u5165\u6b64\u4ee3\u78bc\u767b\u5165",
|
|
|
+ "\u8f93\u5165\u6b64\u4ee3\u7801\u767b\u5f55"
|
|
|
+ };
|
|
|
+ for (String startStr : startStrs) {
|
|
|
+ if (text.contains(startStr)) {
|
|
|
+ String verifyCode = getNetflixCodePattern(StrUtil.subAfter(text, startStr, false));
|
|
|
+ if (StrUtil.isNotBlank(verifyCode)) {
|
|
|
+ return verifyCode;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return StrUtil.EMPTY;
|
|
|
+ }
|
|
|
+
|
|
|
private boolean isNetflixLoginCodeMail(String body) {
|
|
|
return body.contains("\u767b\u5f55\u4ee3\u7801")
|
|
|
|| body.contains("\u767b\u9304\u4ee3\u78bc")
|