Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #269 from meower-media-co/develop
Browse files Browse the repository at this point in the history
feat: MFA credentials combined with password for older client compatibility
  • Loading branch information
tnix100 authored Aug 8, 2024
2 parents 4fa1ab5 + f1c353f commit 57f8039
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
18 changes: 17 additions & 1 deletion database.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from utils import log

CURRENT_DB_VERSION = 8
CURRENT_DB_VERSION = 9

# Create Redis connection
log("Connecting to Redis...")
Expand Down Expand Up @@ -290,6 +290,22 @@ def get_total_pages(collection: str, query: dict, page_size: int = 25) -> int:
log("[Migrator] Adding post replies to database")
db.posts.update_many({"reply_to": {"$exists": False}}, {"$set": {"reply_to": []}})

# Fix MFA recovery codes
log("[Migrator] Fixing MFA recovery codes")
for user in db.usersv0.aggregate([
{"$match": {"mfa_recovery_code": {"$ne": None}}},
{"$project": {
"mfa_recovery_code": 1,
"length": {"$strLenCP": "$mfa_recovery_code"}
}},
{"$match": {
"length": {"$gt": 10}
}}
]):
db.usersv0.update_one({"_id": user["_id"]}, {"$set": {
"mfa_recovery_code": user["mfa_recovery_code"][:10]
}})

db.config.update_one({"_id": "migration"}, {"$set": {"database": CURRENT_DB_VERSION}})
log(f"[Migrator] Finished Migrating DB to version {CURRENT_DB_VERSION}")

Expand Down
22 changes: 21 additions & 1 deletion rest_api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,27 @@ async def login(data: AuthRequest):
# Check credentials
if data.password not in account["tokens"]:
# Check password
if not security.check_password_hash(data.password, account["pswd"]):
password_valid = security.check_password_hash(data.password, account["pswd"])

# Maybe they put their MFA credentials at the end of their password?
if (not password_valid) and db.authenticators.count_documents({"user": account["_id"]}, limit=1):
if (not data.mfa_recovery_code) and data.password.endswith(account["mfa_recovery_code"]):
try:
data.mfa_recovery_code = data.password[-10:]
data.password = data.password[:-10]
except: pass
else:
password_valid = security.check_password_hash(data.password, account["pswd"])
elif not data.totp_code:
try:
data.totp_code = int(data.password[-6:])
data.password = data.password[:-6]
except: pass
else:
password_valid = security.check_password_hash(data.password, account["pswd"])

# Abort if password is invalid
if not password_valid:
security.ratelimit(f"login:u:{account['_id']}", 5, 60)
abort(401)

Expand Down
2 changes: 1 addition & 1 deletion security.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def create_account(username: str, password: str, ip: str):
"avatar_color": "000000",
"quote": "",
"pswd": hash_password(password),
"mfa_recovery_code": secrets.token_hex(10),
"mfa_recovery_code": secrets.token_hex(5),
"tokens": [],
"flags": 0,
"permissions": 0,
Expand Down

0 comments on commit 57f8039

Please sign in to comment.