diff --git a/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/registerServey.kt b/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/registerServey.kt index 5554f9e6..84e37306 100644 --- a/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/registerServey.kt +++ b/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/registerServey.kt @@ -62,7 +62,7 @@ data class SurveyData( @Serializable(with = YesNoSerializer::class) val rspns00: Boolean = true, val rspns01: String = "1", val rspns02: String = "1", - val rspns03: String? = null, + val rspns03: String = "1", val rspns04: String? = null, val rspns05: String? = null, val rspns06: String? = null, diff --git a/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/validatePassword.kt b/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/validatePassword.kt index 6f4e9785..e719dbb2 100644 --- a/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/validatePassword.kt +++ b/api/src/main/kotlin/com/lhwdev/selfTestMacro/api/validatePassword.kt @@ -24,15 +24,82 @@ val transkeyUrl: URL = URL("https://hcs.eduro.go.kr/transkeyServlet") /* * usersId token --(validatePassword)--> users token(temporary) --(selectUserGroup)--> user token */ - sealed class PasswordResult { abstract val isSuccess: Boolean + + @Serializable + data class Success( + @Serializable(YesNoSerializer::class) + @SerialName("pInfAgrmYn") + val agreement: Boolean, + + val token: UsersToken + ) : PasswordResult() { + override val isSuccess: Boolean get() = true + } + + // {isError: true, statusCode: 252, errorCode: 1001, data: {failCnt: 1, canInitPassword: false}} + /* switch(e.data.errorCode): + * case 1000: + * var t = "비밀번호를 5회 틀리셔서 5분후 재시도 하실 수 있습니다."; + * void 0 != e.data.data && void 0 != e.data.data.remainMinutes && (t += "\n약 ".concat(e.data.data.remainMinutes, "분 남았습니다")), + * 5 === e.data.data.failCnt && (t += "\n비밀번호를 잊으셨나요? 학교(기관)로 문의 바랍니다."), + * alert(t); + * break; + * case 1001: + * if (!1 === e.data.data.canInitPassword) { + * var n = "사용자 비밀번호가 맞지 않습니다. \n본인이나 가족이 이미 설정한 비밀번호를 입력하여 주시기 바랍니다.\n5회 틀리실 경우 5분후에 재시도 가능합니다 \n" + "현재 ".concat(e.data.data.failCnt, "회 틀리셨습니다"); + * alert(n) + * } + * break; + * case 1003: + * alert("비밀번호가 초기화 되었습니다.\n다시 로그인하세요") + */ + @Serializable + data class Failed( + val isError: Boolean, + val statusCode: Int, + val errorCode: Int, + val data: Data + ) : PasswordResult() { + override val isSuccess get() = false + + val errorMessage: String? = when(statusCode) { + 252 -> when(errorCode) { + 1000 -> "비밀번호를 5회 틀려서 5분후 재시도 하실 수 있어요." + 1001 -> """ + 사용자 비밀번호가 맞지 않아요. + 본인이나 가족이 이미 설정한 비밀번호를 입력해 주세요. + 5회 틀리실 경우 5분후에 재시도할 수 있어요. + 현재 ${data.failedCount}회 틀리셨습니다. + """.trimIndent() + 1003 -> "비밀번호가 초기화되었으니 다시 로그인해주세요." + else -> null + } + 255 -> when(errorCode) { + 1004 -> "입력시간이 초과되어 다시 비밀번호를 입력해주세요." + else -> null + } + else -> null + } + + override fun toString(): String = when(errorCode) { + 1000 -> "비밀본호를 5회 틀리셔서 5분 후 재시도하실 수 있습니다." + 1001 -> "비밀번호가 맞지 않습니다. 현재 ${data.failedCount}회 실패하셨습니다." + 1003 -> "비밀번호가 초기화되었습니다. 다시 로그인하세요." + else -> "알 수 없는 오류: 에러코드 $errorCode (틀린 횟수: ${data.failedCount})" + } + + @Serializable + data class Data( + @SerialName("failCnt") val failedCount: Int + ) + } + } @Serializable(UsersToken.Serializer::class) -data class UsersToken(val token: String) : PasswordResult() { - override val isSuccess get() = true - +data class UsersToken(val token: String) { object Serializer : KSerializer { override val descriptor = PrimitiveSerialDescriptor(UsersToken::class.java.name, PrimitiveKind.STRING) override fun deserialize(decoder: Decoder) = UsersToken(decoder.decodeString()) @@ -42,44 +109,6 @@ data class UsersToken(val token: String) : PasswordResult() { } } -// {isError: true, statusCode: 252, errorCode: 1001, data: {failCnt: 1, canInitPassword: false}} -/* switch(e.data.errorCode): - * case 1000: - * var t = "비밀번호를 5회 틀리셔서 5분후 재시도 하실 수 있습니다."; - * void 0 != e.data.data && void 0 != e.data.data.remainMinutes && (t += "\n약 ".concat(e.data.data.remainMinutes, "분 남았습니다")), - * 5 === e.data.data.failCnt && (t += "\n비밀번호를 잊으셨나요? 학교(기관)로 문의 바랍니다."), - * alert(t); - * break; - * case 1001: - * if (!1 === e.data.data.canInitPassword) { - * var n = "사용자 비밀번호가 맞지 않습니다. \n본인이나 가족이 이미 설정한 비밀번호를 입력하여 주시기 바랍니다.\n5회 틀리실 경우 5분후에 재시도 가능합니다 \n" + "현재 ".concat(e.data.data.failCnt, "회 틀리셨습니다"); - * alert(n) - * } - * break; - * case 1003: - * alert("비밀번호가 초기화 되었습니다.\n다시 로그인하세요") - */ -@Serializable -data class PasswordWrong( - val isError: Boolean, - val statusCode: Int, - val errorCode: Int, - val data: Data -) : PasswordResult() { - override val isSuccess get() = false - - override fun toString(): String = when(errorCode) { - 1000 -> "비밀본호를 5회 틀리셔서 5분 후 재시도하실 수 있습니다." - 1001 -> "비밀번호가 맞지 않습니다. 현재 ${data.failedCount}회 실패하셨습니다." - 1003 -> "비밀번호가 초기화되었습니다. 다시 로그인하세요." - else -> "알 수 없는 오류: 에러코드 $errorCode (틀린 횟수: ${data.failedCount})" - } - - @Serializable - data class Data( - @SerialName("failCnt") val failedCount: Int - ) -} private val json = Json { ignoreUnknownKeys = true } @@ -132,21 +161,9 @@ suspend fun Session.validatePassword( } ).getText() - fun parseResultToken(): UsersToken { - val userToken = result.removeSurrounding("\"") - require(userToken.startsWith("Bearer")) { "Malformed users token $userToken" } - return UsersToken(userToken) - } - - if(result.startsWith('\"')) return try { - parseResultToken() - } catch(e: Throwable) { - json.decodeFromString(PasswordWrong.serializer(), result) - } - return try { - json.decodeFromString(PasswordWrong.serializer(), result) + json.decodeFromString(PasswordResult.Success.serializer(), result) } catch(e: Throwable) { - parseResultToken() + json.decodeFromString(PasswordResult.Failed.serializer(), result) } } diff --git a/app/src/main/java/com/lhwdev/selfTestMacro/FirstActivity.kt b/app/src/main/java/com/lhwdev/selfTestMacro/FirstActivity.kt index c53046b0..ead837b3 100644 --- a/app/src/main/java/com/lhwdev/selfTestMacro/FirstActivity.kt +++ b/app/src/main/java/com/lhwdev/selfTestMacro/FirstActivity.kt @@ -8,7 +8,6 @@ import android.view.ViewGroup import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager import android.widget.ArrayAdapter -import android.widget.EditText import android.widget.Filter import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity @@ -192,17 +191,18 @@ class FirstActivity : AppCompatActivity() { }) } ?: return@main - val token = catchErrorThanToast { + val result = catchErrorThanToast { tryAtMost(maxTrial = 3) { session.validatePassword(instituteInfo, userIdentifier, password) } } ?: return@main - if(token is PasswordWrong) { - showToastSuspendAsync(token.toString()) + if(result is PasswordResult.Failed) { + showToastSuspendAsync(result.toString()) return@main } - require(token is UsersToken) + require(result is PasswordResult.Success) + val token = result.token val groups = tryAtMost(maxTrial = 3) { session.getUserGroup(instituteInfo, token) @@ -210,7 +210,8 @@ class FirstActivity : AppCompatActivity() { singleOfUserGroup(groups) ?: return@main // TODO: many users pref.institute = instituteInfo - pref.user = UserLoginInfo(userIdentifier, instituteInfo, birth, LoginType.school, password/*, token*/) + pref.user = + UserLoginInfo(userIdentifier, instituteInfo, birth, LoginType.school, password/*, token*/) pref.setting = UserSetting( loginType = LoginType.school, // TODO region = sRegions.getValue(input_region.text.toString()), diff --git a/app/src/main/java/com/lhwdev/selfTestMacro/MainActivity.kt b/app/src/main/java/com/lhwdev/selfTestMacro/MainActivity.kt index 5b62dd31..ed576e4f 100644 --- a/app/src/main/java/com/lhwdev/selfTestMacro/MainActivity.kt +++ b/app/src/main/java/com/lhwdev/selfTestMacro/MainActivity.kt @@ -19,10 +19,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.text.HtmlCompat import androidx.core.view.setPadding import androidx.lifecycle.lifecycleScope -import com.lhwdev.selfTestMacro.api.UsersToken -import com.lhwdev.selfTestMacro.api.getUserGroup -import com.lhwdev.selfTestMacro.api.getUserInfo -import com.lhwdev.selfTestMacro.api.validatePassword +import com.lhwdev.selfTestMacro.api.* import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.content_main.* import kotlinx.coroutines.Dispatchers @@ -72,7 +69,11 @@ class MainActivity : AppCompatActivity() { val detailedUserInfo = try { val usersIdentifier = user.findUser(session) - val usersToken = session.validatePassword(institute, usersIdentifier, user.password) as UsersToken + val usersToken = (session.validatePassword( + institute, + usersIdentifier, + user.password + ) as PasswordResult.Success).token val users = session.getUserGroup(institute, usersToken) session.getUserInfo(institute, singleOfUserGroup(users)!!) } catch(e: Throwable) { diff --git a/app/src/main/java/com/lhwdev/selfTestMacro/selfTestUtils.kt b/app/src/main/java/com/lhwdev/selfTestMacro/selfTestUtils.kt index 34b010cc..b8b020f0 100644 --- a/app/src/main/java/com/lhwdev/selfTestMacro/selfTestUtils.kt +++ b/app/src/main/java/com/lhwdev/selfTestMacro/selfTestUtils.kt @@ -59,8 +59,10 @@ suspend fun Context.submitSuspend(session: Session, notification: Boolean = true // } val usersIdentifier = loginInfo.findUser(session) - val usersToken = session.validatePassword(institute, usersIdentifier, loginInfo.password) as? UsersToken - ?: error("잘못된 비밀번호입니다.") + val usersToken = + (session.validatePassword(institute, usersIdentifier, loginInfo.password) as? PasswordResult.Success + ?: error("잘못된 비밀번호입니다.") + ).token val users = session.getUserGroup(institute, usersToken)