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

@@ -109,6 +109,24 @@ class UserApi internal constructor(
onComplete: (Result<AuthSession>) -> Unit,
): CancellableRequest = submit(onComplete) { requestBlocking("api/v1/auth/login", username, password, auth = false) }
fun ssoExchange(
accessToken: String,
onComplete: (Result<SsoExchangeResult>) -> Unit,
): CancellableRequest = submit(onComplete) {
val root = JSONObject().put("access_token", accessToken)
val response = request("api/v1/auth/sso/exchange", body = root.toString(), method = "POST")
parseSsoExchangeResult(JSONObject(response))
}
fun ssoBindPhone(
token: String,
phone: String,
onComplete: (Result<Unit>) -> Unit,
): CancellableRequest = submitUnit(onComplete, token) {
val root = JSONObject().put("phone", phone)
request("api/v1/auth/sso/bind-phone", token = token, body = root.toString(), method = "POST")
}
fun courses(
token: String,
onComplete: (Result<List<Course>>) -> Unit,
@@ -279,4 +297,25 @@ class UserApi internal constructor(
),
)
}
private fun parseSsoExchangeResult(root: JSONObject): SsoExchangeResult {
val user = root.getJSONObject("user")
return SsoExchangeResult(
token = root.getString("token"),
user = AuthUser(
id = user.getString("id"),
username = user.getString("username"),
nickname = user.getString("nickname"),
),
phoneBound = root.optBoolean("phone_bound", false),
isNewUser = root.optBoolean("is_new_user", false),
)
}
}
data class SsoExchangeResult(
val token: String,
val user: AuthUser,
val phoneBound: Boolean,
val isNewUser: Boolean,
)