17 Commits

Author SHA1 Message Date
db157771de Merge flags 2024-04-08 16:51:43 +02:00
cbd1ad93a6 version bump 2024-04-08 16:38:16 +02:00
afabd94f0d Re-implement cookie login
with chrome profiles
2024-04-08 16:36:38 +02:00
81deaf05b0 Update chrome.deb URL 2024-04-08 16:34:36 +02:00
9af0f4aadb build.sh: check permissions 2024-04-03 15:42:14 +02:00
1d16294c04 Add more logs (custom.txt..) to logs view 2024-04-03 15:34:46 +02:00
fae2033061 Simplify Dockerfile to cache building layers 2024-04-03 15:26:02 +02:00
50c4036c73 Merge pull request 'Fix ANSI code formatting' (#9) from augustin64/MsRewards-Reborn:master into master
Reviewed-on: https://gitea.augustin64.fr/piair/MsRewards-Reborn/pulls/9
2024-03-31 12:05:17 +02:00
c683472895 Fix ANSI code formatting 2024-03-29 16:53:59 +01:00
178f2d472a Merge pull request 'Mise en forme des codes ANSI dans les logs' (#8) from augustin64/MsRewards-Reborn:augustin64-ansi-up into master
Reviewed-on: https://gitea.augustin64.fr/piair/MsRewards-Reborn/pulls/8
2024-03-28 23:56:33 +01:00
d3137f858a Mise en forme des codes ANSI dans les logs 2024-03-25 10:41:34 +01:00
d2ad467d4e Oops, pas push le bon fichier 2024-03-24 20:30:09 +01:00
b45e9e549f mise à jour automatique de chrome 2024-03-24 20:27:40 +01:00
200b0d8a86 Trying to fix an issue when an account fail 2024-03-05 21:18:39 +01:00
4a5af6455d Fixed 2FA issue + added better logs 2024-03-01 17:29:15 +01:00
49b691d736 not tested enough apparently 2024-02-28 18:22:15 +01:00
9549a6dea3 not tested enough apparently 2024-02-28 18:12:32 +01:00
13 changed files with 196 additions and 38 deletions

View File

@ -1,21 +1,39 @@
FROM python:3.10
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /app/
RUN apt update \
&& wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& apt install redis libgtk-4-1 libvulkan1 libxdamage1 -y \
&& curl -sSLO https://nc.piair.xyz/s/BKLsBWoZkTdYjfq/download/chrome.deb \
&& ln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime \
&& git clone https://gitea.augustin64.fr/piair/MsRewards-Reborn \
&& python3 -m pip install -r MsRewards-Reborn/requirements.txt \
&& wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key \
&& curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list \
&& apt update \
&& apt install novnc websockify grafana xvfb nginx nano tzdata sqlite3 apt-transport-https software-properties-common wget wfrench tigervnc-standalone-server libasound2 libatk-bridge2.0-0 libnss3 libnspr4 xvfb libgbm1 libatk1.0-0 libu2f-udev libatspi2.0-0 libcups2 libxkbcommon0 libxrandr2 libdbus-1-3 xdg-utils fonts-liberation libdrm2 -y \
&& bash MsRewards-Reborn/config/config.sh \
# Initial apt install
RUN apt update
RUN apt install -y libgtk-4-1 libvulkan1 libxdamage1 \
novnc websockify xvfb nginx nano tzdata \
sqlite3 apt-transport-https software-properties-common \
wget wfrench tigervnc-standalone-server libasound2 \
libatk-bridge2.0-0 libnss3 libnspr4 xvfb libgbm1 libatk1.0-0 \
libu2f-udev libatspi2.0-0 libcups2 libxkbcommon0 libxrandr2 \
libdbus-1-3 xdg-utils fonts-liberation libdrm2
# Additional repos and packages
RUN wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb
RUN curl -sSL http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/google-chrome-stable_123.0.6312.86-1_amd64.deb -o chrome.deb \
&& dpkg -i chrome.deb
RUN ln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime
RUN wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key \
&& echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list
RUN curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
# Install from new repo
RUN apt update \
&& apt install -y redis grafana
COPY requirements.txt /app/requirements.txt
RUN python3 -m pip install -r requirements.txt
# Setup app
RUN git clone https://gitea.augustin64.fr/piair/MsRewards-Reborn
# Use this instead when developping locally:
# COPY . /app/MsRewards-Reborn
RUN bash MsRewards-Reborn/config/config.sh
ENV TZ="Europe/Paris"
WORKDIR /app/MsRewards-Reborn/Flask/

View File

@ -373,8 +373,18 @@ def config_post():
def logs():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
print(configs)
return(render_template("logs.html", data=configs))
files = [(configs[i]["name"], i) for i in configs]
config_files = [i[1] for i in files]
for f in os.listdir("/app/MsRewards-Reborn/Flask/static/logs"):
fid = ".".join(f.split(".")[:-1]) # filename without .txt
if f != ".gitignore" and fid not in config_files:
files.append((f, fid))
return render_template(
"logs.html",
files=files
)
@app.route("/stats/", methods=["GET", "POST"])

View File

@ -8,14 +8,37 @@
<select name="select" onchange="change_logs(this.value)">
<option id="null" value="0">Choisir une config</option>
{% for i in data %}
<option id="{{data[i]['name']}}" value="{{i}}">{{data[i]['name']}}</option>
{% for file in files %}
<option id="{{ file[0] }}" value="{{ file[1] }}">{{ file[0] }}</option>
{% endfor %}
</select>
<br><br>
<iframe type="text/html" src="{{url_for('static', filename='logs/1.txt')}}" width="100%" height="85%" id="embed">
<iframe type="text/html" src="{{url_for('static', filename='logs/1.txt')}}" width="100%" height="85%" id="embed"></iframe>
<script defer>
const iframe = document.getElementsByTagName("iframe")[0];
var script = document.createElement('script');
// Wait until ansi_up load
script.onload = function () {
// Wait until iframe load
iframe.onload = function() {
const subdoc = iframe.contentWindow.document;
const subBody = subdoc.getElementsByTagName("body")[0]
let ansiOutput = subBody;
// Depending on the content encoding (and maybe on the browser)
// a <pre> is added around the content of the file
if (subBody.getElementsByTagName("pre").length > 0) {
ansiOutput = subBody.getElementsByTagName("pre")[0];
}
const ansi_up = new AnsiUp();
ansiOutput.innerHTML = ansi_up.ansi_to_html(ansiOutput.innerText);
}
};
script.src = "https://cdn.jsdelivr.net/npm/ansi_up@4.0.4/ansi_up.js";
document.head.appendChild(script);
</script>
{% endif %}
{% endblock %}

55
V6.py
View File

@ -1,4 +1,4 @@
#!/usr/bin/python3.10
#!/usr/bin/python3
from modules.Classes.Config import Config
from modules.Classes.DiscordLogger import DiscordLogger
from modules.Classes.UserCredentials import UserCredentials
@ -9,6 +9,7 @@ from modules.db import add_to_database
from modules.driver_tools import *
from modules.error import *
import os
# create a webdriver
def create_driver(mobile=False):
@ -22,14 +23,34 @@ def create_driver(mobile=False):
"AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/22 Mobile Safari/537.36"
)
chrome_options = webdriver.ChromeOptions()
# Profile dir
chrome_profile_dir = "/app/MsRewards-Reborn/user_data/profile/"+config.UserCredentials.get_mail()
os.makedirs(chrome_profile_dir, exist_ok=True)
# Full list on https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md
arguments = [
"--no-first-run",
"--ash-no-nudges",
"--no-default-browser-check",
"--disable-features=PrivacySandboxSettings4,Translate",
"--disable-search-engine-choice-screen",
f"--user-data-dir={chrome_profile_dir}/"
]
if mobile:
chrome_options.add_argument(f"--user-agent={mobile_user_agent}")
arguments.append(f"--user-agent={mobile_user_agent}")
else:
chrome_options.add_argument(f"--user-agent={pc_user_agent}")
arguments.append(f"--user-agent={pc_user_agent}")
# disabled as it may cause detection
if config.proxy.is_enabled():
chrome_options.add_argument(f'--proxy-server={config.proxy.ip}:{config.proxy.port}')
arguments.append(f'--proxy-server={config.proxy.ip}:{config.proxy.port}')
chrome_options = webdriver.ChromeOptions()
for arg in arguments:
chrome_options.add_argument(arg)
driver = uc.Chrome(options=chrome_options)
set_language(driver)
return driver
@ -152,7 +173,7 @@ def play_quiz4(override: int = None):
except Exception as e:
log_error(e)
raise ValueError(e)
info("Quiz 8 done.")
info("Quiz 4 done.")
custom_sleep(3)
@ -165,6 +186,8 @@ def do_poll():
try:
answer_elem.click()
except exceptions.ElementNotInteractableException:
warning("element not clickable. Waiting a bit and retrying.")
custom_sleep(uniform(2, 2.5))
driver.execute_script("arguments[0].click();", answer_elem)
custom_sleep(uniform(2, 2.5))
except Exception as err:
@ -190,7 +213,7 @@ def all_cards():
info("no promo card")
if len(card_list) < 10: # most likely an error during loading
if "suspendu" in driver.page_source:
if "suspendu" in driver.page_source or "suspended" in driver.page_source:
raise Banned()
driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
@ -410,8 +433,16 @@ def login_part_2():
# login() tries to login to your Microsoft account.
# it uses global variable g._mail and g._password to login
def login():
def logged_in():
driver.get("https://login.live.com")
custom_sleep(10)
if get_domain(driver) == "account.microsoft.com":
return True
return False
driver = config.WebDriver.driver
try:
if not logged_in():
login_part_1()
login_part_2()
driver.get("https://rewards.bing.com/")
@ -610,9 +641,11 @@ def daily_routine(cred: UserCredentials, custom=False):
try:
if not custom: # custom already is logged in
login()
except Banned:
log_error("This account is locked.")
return
raise Banned()
except Identity:
log_error("This account has an issue.")
return
@ -680,7 +713,7 @@ def json_start(json_entry, cred: UserCredentials):
login()
try:
if str(account_id) in json_entry["tout"]:
daily_routine(cred)
daily_routine(cred, True)
except KeyError:
pass
else:
@ -744,12 +777,16 @@ def default_start():
config.WebDriver.pc_driver.quit()
config.display.stop()
break
except Banned:
warning("this account is banned. Switching to next account")
except Exception as e:
log_error(f"Error not caught. Skipping this account. " + format_error(e))
critical(f"Error not caught. Skipping this account. {e}")
config.WebDriver.pc_driver.quit()
finally:
config.UserCredentials.next_account()
config.display.stop()

View File

@ -1 +1,12 @@
sudo docker build --no-cache --network host -t msrewards . && sudo docker run -d --restart unless-stopped -p 1234:1234 -p 2345:2345 -ti --shm-size=2gb --name MsRewards msrewards
#!/bin/bash
docker-do () { # Check if sudo needs to be used
if id -nG "$(whoami)" | grep -qw "docker"; then
docker $@
else
sudo docker $@
fi
}
docker-do build --network host -t msrewards .
docker-do run -d --restart unless-stopped -p 1234:1234 -p 2345:2345 -ti --shm-size=2gb --name MsRewards msrewards

View File

@ -30,7 +30,7 @@ class DiscordLogger:
)
file = File("screenshot.png")
embed.set_image(url="attachment://screenshot.png")
embed.set_footer(text=self.config.UserCredentials.creds.get_mail())
embed.set_footer(text=self.config.UserCredentials.get_mail() + " - " + self.config.WebDriver.current_driver())
self.config.discord.wh.send(embed=embed, username="error", file=file, avatar_url=self.config.discord.avatar_url)
self.config.discord.wh.send(username="error", file=File("page.html"), avatar_url=self.config.discord.avatar_url)

View File

@ -20,3 +20,6 @@ class Driver:
case _:
raise ValueError("The driver must be either pc or mobile")
def current_driver(self):
return "PC" if self.pc_driver == self.driver else "Mobile"

View File

@ -31,7 +31,7 @@ class UserCredentials:
def get_tfa(self):
if not self.tfa_enable():
warning("Warning: TFA is not enabled. Calling get_tfa is an expected behaviour.")
return TOTP(self.data[self.current]["tfa"])
return TOTP(self.data[self.current]["2fa"])
def next_account(self):
self.current += 1

View File

@ -0,0 +1,8 @@
import undetected_chromedriver as uc
from pyvirtualdisplay.smartdisplay import SmartDisplay
display = SmartDisplay(size=(1920, 1080))
display.start()
driver = uc.Chrome()
driver.close()
driver.close()

View File

@ -30,7 +30,7 @@ class ColoredFormatter(logging.Formatter):
# Set up the root logger
root_logger = logging.getLogger(__name__)
root_logger.setLevel(logging.DEBUG)
root_logger.setLevel(logging.INFO)
# Create a console handler and set the formatter
ch = logging.StreamHandler()

View File

@ -10,7 +10,7 @@ def get_domain(driver):
def custom_sleep(temps):
try:
if True: # todo: change this awful condition
if False: # todo: change this awful condition
points = ["", "", "", "", "", "", "", ""]
passe = 0
for _ in range(int(temps)):

View File

@ -0,0 +1,48 @@
import requests
import re
from packaging import version
import subprocess
from logger import critical, info, error
errorMessage = subprocess.run(['python3', 'generate_error.py'], check=False, stdout=subprocess.PIPE,
stderr=subprocess.PIPE).stderr.decode("utf-8")
versionPattern = "This version of ChromeDriver only supports Chrome version ([0-9]+)"
try:
versionN = re.search(versionPattern, errorMessage)[1]
except Exception as e:
critical("Can't get version number from error")
error(e)
exit(0)
info(f"Needed version : '{versionN}'")
downloadUrl = "http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/"
r = requests.get(downloadUrl)
content = r.text
exactVersionList = re.findall(f"(google-chrome-stable_({versionN}.[0-9.]+)[^<^>^\"]+)", content)
try:
best = exactVersionList[0]
except Exception as e:
critical("No version matches required version")
error(e)
exit(0)
for i in exactVersionList:
if version.parse(i[1]) > version.parse(best[1]):
best = i
chromeDebURL = f"http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/{best[0]}"
info(f"chrome deb URL : {chromeDebURL}")
info("downloading chrome")
subprocess.call(['wget', "-O", "/tmp/chrome.deb", chromeDebURL])
info("Chrome deb downloaded. Installing chrome")
subprocess.call(["dpkg", "-i", "/tmp/chrome.deb"])
info("Chrome installed")

View File

@ -1 +1 @@
v6.8.38
v6.8.43