- 
                Notifications
    You must be signed in to change notification settings 
- Fork 317
Description
import re
import random
import smtplib
import bcrypt
import pyotp
import sqlite3
import requests
import time
import platform
import win32com.client  # Windows Hello API (Fingerprint)
from flask import Flask, render_template, request, redirect, session, jsonify
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from datetime import datetime
Initialize Flask App
app = Flask(name)
app.secret_key = "supersecretkey"  # Change this for security
Setup Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login_page"
------------------ DATABASE SETUP ------------------
def setup_database():
"""Creates users and login_history tables with role support."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
# Users Table with Fingerprint Support
c.execute(
    """CREATE TABLE IF NOT EXISTS users (
        email TEXT PRIMARY KEY, 
        phone TEXT, 
        password_hash TEXT, 
        fingerprint_hash TEXT, 
        otp_secret TEXT,
        role TEXT DEFAULT 'user')"""
)
# Login History Table
c.execute(
    """CREATE TABLE IF NOT EXISTS login_history (
        email TEXT, 
        device TEXT, 
        ip_address TEXT, 
        city TEXT,
        country TEXT,
        timestamp TEXT,
        last_activity TEXT,
        session_active INTEGER DEFAULT 1,
        FOREIGN KEY(email) REFERENCES users(email))"""
)
conn.commit()
conn.close()
------------------ USER MODEL FOR FLASK-LOGIN ------------------
class User(UserMixin):
def init(self, email, role):
self.id = email
self.role = role
@login_manager.user_loader
def load_user(email):
"""Loads the user from the database."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT role FROM users WHERE email=?", (email,))
user_data = c.fetchone()
conn.close()
if user_data:
    return User(email, user_data[0])
return None
------------------ WINDOWS HELLO FINGERPRINT AUTHENTICATION ------------------
def authenticate_fingerprint():
"""Authenticates user via Windows Hello fingerprint scanner."""
try:
bio = win32com.client.Dispatch("WinBioCredentialProvider.WinBioCredentialProvider")
result = bio.Validate()
return result  # True if authentication succeeds
except Exception as e:
print("Fingerprint authentication failed:", str(e))
return False
@app.route("/fingerprint-login", methods=["POST"])
def fingerprint_login():
"""Logs in a user using Windows Hello fingerprint authentication."""
email = request.form["email"]
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT role FROM users WHERE email=?", (email,))
user_data = c.fetchone()
conn.close()
if user_data:
    role = user_data[0]
    if authenticate_fingerprint():
        user = User(email, role)
        login_user(user)
        return redirect("/dashboard")
    else:
        return "Fingerprint authentication failed", 401
return "User not found", 404
------------------ LOGIN FUNCTION WITH PASSWORD AUTH ------------------
@app.route("/login", methods=["GET", "POST"])
def login_page():
if request.method == "POST":
email = request.form["email"]
password = request.form["password"]
    conn = sqlite3.connect("users.db")
    c = conn.cursor()
    c.execute("SELECT password_hash, role FROM users WHERE email=?", (email,))
    user_data = c.fetchone()
    conn.close()
    if user_data:
        stored_password_hash, role = user_data
        if bcrypt.checkpw(password.encode(), stored_password_hash.encode()):
            user = User(email, role)
            login_user(user)
            return redirect("/dashboard")
    
    return "Invalid email or password", 401
return render_template("login.html")
------------------ DASHBOARD FOR USERS ------------------
@app.route("/dashboard")
@login_required
def user_dashboard():
"""User dashboard - shows login history for normal users."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT * FROM login_history WHERE email=?", (current_user.id,))
login_history = c.fetchall()
conn.close()
return render_template("dashboard.html", logins=login_history, user=current_user)
------------------ ADMIN PANEL ------------------
@app.route("/admin")
@login_required
def admin_dashboard():
"""Admin panel - only accessible to admins."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT * FROM login_history ORDER BY timestamp DESC")
login_data = c.fetchall()
conn.close()
return render_template("admin.html", logins=login_data, user=current_user)
------------------ LOGOUT ------------------
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect("/login")
if name == "main":
setup_database()
app.run(debug=True)