forked from 3wordchant/capsul-flask
		
	fixing login email case sensitivity issues
This commit is contained in:
		| @ -43,17 +43,28 @@ def login(): | ||||
| 	        errors.append("enter a valid email address") | ||||
|  | ||||
|         if len(errors) == 0: | ||||
|             token = get_model().login(email) | ||||
|             result = get_model().login(email) | ||||
|             token = result[0] | ||||
|             ignoreCaseMatches = result[1] | ||||
|             if token is None: | ||||
|                 errors.append("too many logins. please use one of the existing login links that have been emailed to you") | ||||
|             else: | ||||
|                 link = f"{current_app.config['BASE_URL']}/auth/magic/{token}" | ||||
|                  | ||||
|                 message = (f"Navigate to {link} to log into Capsul.\n" | ||||
|                             "\nIf you didn't request this, ignore this message.") | ||||
|  | ||||
|                 if len(ignoreCaseMatches) > 0: | ||||
|                   joinedMatches = " or ".join(ignoreCaseMatches) | ||||
|                   message = (f"You tried to log in as '{email}', but that account doesn't exist yet. " | ||||
|                               "If you would like to create a new account for '{email}', click here {link} " | ||||
|                               "If you meant to log in as {joinedMatches}, please return to capsul.org " | ||||
|                               "and log in again with the correct (case-sensitive) email address.") | ||||
|  | ||||
|                 current_app.config["FLASK_MAIL_INSTANCE"].send( | ||||
|                     Message( | ||||
|                         "Click This Link to Login to Capsul", | ||||
|                         body=(f"Navigate to {link} to log into Capsul.\n" | ||||
|                                "\nIf you didn't request this, ignore this message."), | ||||
|                         body=message, | ||||
|                         recipients=[email] | ||||
|                     ) | ||||
|                 ) | ||||
|  | ||||
| @ -40,7 +40,7 @@ def init_app(app): | ||||
|   hasSchemaVersionTable = False | ||||
|   actionWasTaken = False | ||||
|   schemaVersion = 0 | ||||
|   desiredSchemaVersion = 8 | ||||
|   desiredSchemaVersion = 9 | ||||
|  | ||||
|   cursor = connection.cursor() | ||||
|  | ||||
|  | ||||
| @ -10,18 +10,26 @@ class DBModel: | ||||
|  | ||||
|   def login(self, email): | ||||
|     self.cursor.execute("SELECT * FROM accounts WHERE email = %s", (email, )) | ||||
|     if len(self.cursor.fetchall()) == 0: | ||||
|       self.cursor.execute("INSERT INTO accounts (email) VALUES (%s)", (email, )) | ||||
|     hasExactMatch = len(self.cursor.fetchall()) | ||||
|     self.cursor.execute("SELECT * FROM accounts WHERE email = %s AND ever_logged_in = TRUE", (email, )) | ||||
|     everLoggedIn = len(self.cursor.fetchall()) | ||||
|     ignoreCaseMatches = [] | ||||
|     if everLoggedIn == 0: | ||||
|       self.cursor.execute("SELECT email FROM accounts WHERE lower_case_email = %s", (email.lower(), )) | ||||
|       ignoreCaseMatches = self.cursor.fetchall() | ||||
|    | ||||
|     if hasExactMatch == 0: | ||||
|       self.cursor.execute("INSERT INTO accounts (email, lower_case_email) VALUES (%s, %s)", (email, email.lower())) | ||||
|  | ||||
|     self.cursor.execute("SELECT token FROM login_tokens WHERE email = %s", (email, )) | ||||
|     if len(self.cursor.fetchall()) > 2: | ||||
|       return None | ||||
|       return (None, ignoreCaseMatches) | ||||
|  | ||||
|     token = generate() | ||||
|     self.cursor.execute("INSERT INTO login_tokens (email, token) VALUES (%s, %s)", (email, token)) | ||||
|     self.connection.commit() | ||||
|  | ||||
|     return token | ||||
|     return (token, ignoreCaseMatches) | ||||
|      | ||||
|   def consume_token(self, token): | ||||
|     self.cursor.execute("SELECT email FROM login_tokens WHERE token = %s and created > (NOW() - INTERVAL '20 min')", (token, )) | ||||
| @ -29,6 +37,7 @@ class DBModel: | ||||
|     if row: | ||||
|       email = row[0] | ||||
|       self.cursor.execute("DELETE FROM login_tokens WHERE email = %s", (email, )) | ||||
|       self.cursor.execute("UPDATE accounts SET ever_logged_in = TRUE WHERE email = %s", (email, )) | ||||
|       self.connection.commit() | ||||
|       return email | ||||
|     return None | ||||
| @ -228,7 +237,7 @@ class DBModel: | ||||
|     if row: | ||||
|       self.cursor.execute( "DELETE FROM unresolved_btcpay_invoices WHERE id = %s", (id,) ) | ||||
|       if not completed: | ||||
|         self.cursor.execute("UPDATE payments SET invalidated = True WHERE email = %s id = %s", (row[0], row[1])) | ||||
|         self.cursor.execute("UPDATE payments SET invalidated = TRUE WHERE email = %s id = %s", (row[0], row[1])) | ||||
|        | ||||
|       self.connection.commit() | ||||
|          | ||||
| @ -249,7 +258,7 @@ class DBModel: | ||||
|     self.connection.commit() | ||||
|  | ||||
|   def all_accounts(self): | ||||
|     self.cursor.execute("SELECT email, account_balance_warning FROM accounts") | ||||
|     self.cursor.execute("SELECT email, account_balance_warning FROM accounts WHERE ever_logged_in = TRUE ") | ||||
|     return list(map(lambda row: dict(email=row[0], account_balance_warning=row[1]), self.cursor.fetchall())) | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										5
									
								
								capsulflask/schema_migrations/09_down_email_case.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								capsulflask/schema_migrations/09_down_email_case.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
|  | ||||
| ALTER TABLE accounts DROP COLUMN lower_case_email; | ||||
| ALTER TABLE accounts DROP COLUMN ever_logged_in; | ||||
|  | ||||
| UPDATE schemaversion SET version = 8; | ||||
							
								
								
									
										10
									
								
								capsulflask/schema_migrations/09_up_email_case.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								capsulflask/schema_migrations/09_up_email_case.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| ALTER TABLE accounts  | ||||
| ADD COLUMN lower_case_email TEXT NULL; | ||||
|  | ||||
| ALTER TABLE accounts  | ||||
| ADD COLUMN ever_logged_in BOOLEAN NOT NULL DEFAULT FALSE; | ||||
|  | ||||
| UPDATE accounts set lower_case_email = LOWER(accounts.email); | ||||
| UPDATE accounts set ever_logged_in = TRUE; | ||||
|  | ||||
| UPDATE schemaversion SET version = 9; | ||||
		Reference in New Issue
	
	Block a user