add d1kt SSO integration: OAuth2 login via WebView + phone binding

This commit is contained in:
2026-08-31 16:50:49 +08:00
parent 3652ebda07
commit daa73e2b98
6 changed files with 454 additions and 0 deletions

View File

@@ -156,6 +156,10 @@ class VideoRepository:
}
if "phone" not in user_columns:
connection.execute("ALTER TABLE users ADD COLUMN phone TEXT")
if "sso_provider" not in user_columns:
connection.execute("ALTER TABLE users ADD COLUMN sso_provider TEXT")
if "phone_bound" not in user_columns:
connection.execute("ALTER TABLE users ADD COLUMN phone_bound INTEGER NOT NULL DEFAULT 0")
connection.execute("CREATE INDEX IF NOT EXISTS idx_attempts_user ON attempts(user_id)")
with self._connect() as connection:
@@ -789,6 +793,43 @@ class VideoRepository:
return None
return self.get_user_by_id(user_id)
def create_sso_user(
self,
*,
username: str,
nickname: str,
email: str = "",
sso_provider: str = "d1kt",
) -> Optional[Dict[str, Any]]:
user_id = uuid.uuid4().hex
now = utc_now()
try:
with self._connect() as connection:
connection.execute(
"""
INSERT INTO users (id, username, nickname, phone, sso_provider, phone_bound, password_hash, created_at)
VALUES (?, ?, ?, NULL, ?, 0, '', ?)
""",
(
user_id,
username.strip().lower(),
(nickname or username).strip()[:80],
sso_provider,
now,
),
)
except sqlite3.IntegrityError:
return None
return self.get_user_by_id(user_id)
def bind_phone(self, user_id: str, phone: str) -> Optional[Dict[str, Any]]:
with self._connect() as connection:
connection.execute(
"UPDATE users SET phone = ?, phone_bound = 1 WHERE id = ?",
(phone.strip()[:20], user_id),
)
return self.get_user_by_id(user_id)
def get_user_by_username(self, username: str) -> Optional[Dict[str, Any]]:
with self._connect() as connection:
row = connection.execute(