diff --git a/app/build.gradle b/app/build.gradle
index 51dd3c295d8f677781cf066465b568c11e449030..6ba7fe0afe3bf9d7ee8791a91bdc17228c2d608c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,8 +11,8 @@ android {
applicationId "jp.atled.agileworks"
minSdkVersion 24
targetSdk 34
- versionCode 3
- versionName "1.1.0"
+ versionCode 4
+ versionName "1.1.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1f6cbec0fd5d735842a5ad99ed3427a7254a30ec..3c450c434ed58604aed9218429dcced4d64cb0ae 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,9 @@
+
+
+
Unit) {
+ fun getSession(onResult: (isSuccess: Boolean, response: SessionResponse?, headers: Map>?) -> Unit) {
val instance = ApiClient.instance(null)
- instance.getSession().enqueue(ApiCallbackCommon(activity, onResult))
+ instance.getSession().enqueue(SessionApiCallback(activity, onResult))
}
companion object {
fun getInstance(activity: Activity?) = SessionRepository(activity)
+
+ fun setCookie(setCookieHeaders: List, bodySessionId: String, url: String){
+ CookieManager.getInstance().apply {
+ val preferences = "cookie" + ServerRepository().loadServer().toString()
+ var cookie = ""
+ for (header in setCookieHeaders) {
+ cookie += header + ";"
+ }
+ // ヘッダからJSESSIONIDを取得
+ val headerSessionId = extractJSessionId(cookie)
+
+ // レスポンスヘッダとボディのJSESSIONIDが同じとき、そのユーザの最新のセッションになる
+ if(bodySessionId == headerSessionId) {
+ for (header in setCookieHeaders) {
+ // Cookieをセット
+ setCookie(url, header)
+ }
+ flush()
+ // Cookieを保存
+ AwApp.instance.applicationContext.getSharedPreferences(
+ preferences,
+ Context.MODE_PRIVATE
+ )
+ .edit()
+ .putString("cookie", cookie)
+ .apply()
+ }
+ }
+ }
+
+ fun extractJSessionId(cookie: String): String? {
+ val startIndex = cookie.indexOf("JSESSIONID=")
+ if (startIndex != -1) {
+ val jsessionIdPart = cookie.substring(startIndex)
+ val parts = jsessionIdPart.split(";")
+ if (parts.isNotEmpty()) {
+ val jsessionIdValuePair = parts[0]
+ val valueParts = jsessionIdValuePair.split("=",)
+ if (valueParts.size == 2) {
+ return valueParts[1]
+ }
+ }
+ }
+ return null
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt b/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt
index 068b008114c4caf13d925d023b40642eab5dacf3..e7247c0e94a3708cba36d643c12f60e8377dc30a 100644
--- a/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt
+++ b/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt
@@ -153,12 +153,12 @@ object ApiClient {
// 保存しているセッションIDを取得
var preferences = "cookie" + ServerRepository().loadServer().toString()
val cookiePref = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE)
- val sessionId = cookiePref.getString("sessionId", "") ?: ""
+ val cookie = cookiePref.getString("cookie", "") ?: ""
interceptor = Interceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
val request = requestBuilder
- .addHeader("Cookie", "JSESSIONID=$sessionId")
+ .addHeader("Cookie", cookie)
.build()
chain.proceed(request)
}
diff --git a/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d8a54bbf95ed966a3d32ce4ffb38c50ca1dc5661
--- /dev/null
+++ b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt
@@ -0,0 +1,50 @@
+package jp.atled.agileworks.model.api
+
+import android.app.Activity
+import android.app.AlertDialog
+import android.util.Log
+import jp.atled.agileworks.R
+import jp.atled.agileworks.view.ui.login.LoginUtil
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class SessionApiCallback(
+ private val activity: Activity?,
+ private val onResult: (isSuccess: Boolean, response: T?, headers: Map>?) -> Unit
+) : Callback {
+
+ companion object {
+ private const val TAG = "SessionApiCallback"
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ try {
+ if (response != null && response.isSuccessful) {
+ val headers = response.headers().toMultimap()
+ onResult(true, response.body(), headers)
+ } else {
+ onResult(false, null, null)
+ }
+ } catch (e: IllegalStateException) {
+ // 非同期処理が画面遷移後に完了したときに発生する。握りつぶす。
+ Log.w(TAG, "IllegalStateException", e)
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ if ((activity != null) && (t is BadRefreshTokenException)) {
+ AlertDialog.Builder(activity)
+ .setTitle(R.string.refresh_token_failure_dialog_title)
+ .setMessage(R.string.refresh_token_failure_dialog_message)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setPositiveButton(R.string.refresh_token_failure_dialog_button_label) { _, _ ->
+ LoginUtil.reauth(activity)
+ }
+ .setCancelable(false)
+ .show()
+ } else {
+ onResult(false, null, null)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt b/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt
index 60c53b5c987a4ca5580aef7a41530c348b551451..166955a317c648283cd559197d017fc89b23de4a 100644
--- a/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt
+++ b/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt
@@ -62,7 +62,7 @@ class DrawerMenu {
}
private fun setupUserName(activity: Activity, drawer: NavigationView) {
- SessionRepository.getInstance(activity).getSession { _, response ->
+ SessionRepository.getInstance(activity).getSession { _, response, _ ->
val userName = response?.user?.name.orEmpty()
var systemName = response?.system_name.orEmpty()
val header = drawer.getHeaderView(0)
@@ -75,7 +75,7 @@ class DrawerMenu {
private fun showProfile(activity: AppCompatActivity) {
// ログイン中に変化があるかもしれないのでメニューが呼ばれる度に取得し直す。
- SessionRepository.getInstance(activity).getSession { _, response ->
+ SessionRepository.getInstance(activity).getSession { _, response, _ ->
val userCode = response?.user?.code.orEmpty()
val userName = response?.user?.name.orEmpty()
val loginId = response?.user?.loginId.orEmpty()
diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt
index 9f6d385bac18a07a0b1a1a6e6ca5d34e3008b85b..f133e2030937f63a598dea22a4a52bf839bbe515 100644
--- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt
+++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt
@@ -151,7 +151,7 @@ class DocumentWebDownloader(private val handlingFragment: Fragment, private val
val openUriIntent = Intent(Intent.ACTION_VIEW, destinationUri).apply {
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
- val pendingIntent = PendingIntent.getActivity(AwApp.instance.applicationContext, 0, openUriIntent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT)
+ val pendingIntent = PendingIntent.getActivity(AwApp.instance.applicationContext, 0, openUriIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT)
progressNotificationBuilder
.setContentText(context.resources.getText(R.string.download_notification_successful_message))
.setSmallIcon(android.R.drawable.stat_sys_download_done)
diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt
index 9e27c64515eb36d85f44ea6884a262355f225107..f516c95814edccd9866785bdd55f841a124d223e 100644
--- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt
+++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt
@@ -566,27 +566,15 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter {
activity = null
}
- SessionRepository.getInstance(activity).getSession() { isSuccess, response ->
+ SessionRepository.getInstance(activity).getSession() { isSuccess, response, headers ->
if (isSuccess) {
url?.let { url ->
val uri = Uri.parse(url)
response!!.session_id?.apply {
sessionId = response!!.session_id
- setCookie(
- "https://${uri.host}",
- "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None"
- )
- flush()
-
- // セッションID保存
- var preferences = "cookie" + ServerRepository().loadServer().toString()
- AwApp.instance.applicationContext.getSharedPreferences(
- preferences,
- Context.MODE_PRIVATE
- )
- .edit()
- .putString("sessionId", sessionId)
- .apply()
+ headers?.get("set-cookie")?.also { setCookieHeaders ->
+ SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}")
+ }
}
if (updateLanguage) {
// 多言語対応
diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt
index 35e82d774fe755a71bbcfa962ddc329b5b37caba..9c28d6b0b16b8f37416e081b56972705afecfb9d 100644
--- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt
+++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt
@@ -51,6 +51,7 @@ class LoginFragment: Fragment() {
private var shouldClearTaskOnOAuthFailure = false
private var disableButtonFlg = false
private var tempServerNumber: Int? = 0
+ private var addServerFlg = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Log.d(TAG, "call onCreateView()")
@@ -124,6 +125,7 @@ class LoginFragment: Fragment() {
} else if (requireActivity().intent.action == LoginActivity.ACTION_ADD_SERVER) {
//サーバー追加のログイン画面
Log.d(TAG, "intent.action == LoginActivity.ACTION_ADD_SERVER")
+ addServerFlg = true
} else {
// 過去に認証したときの authState を取得
if (mOAuthService.getAuthState(savedInstanceState).isAuthorized) {
@@ -178,7 +180,11 @@ class LoginFragment: Fragment() {
binding.viewmodel?.setServerContext()
if (checkServer()) {
- whenAuthorizationSucceeds()
+ if(addServerFlg) {
+ loginAlert(R.string.login_server_check_alert)
+ } else {
+ startAuthorization()
+ }
} else {
try {
startAuthorization()
@@ -253,8 +259,6 @@ class LoginFragment: Fragment() {
for (server in serverList) {
val serverName = LoginRepository(server).loadServerUrl()
if (serverName == serverHost) {
- ServerRepository().setServer(server)
- ServerRepository().changeServerList(server)
return true
}
}
@@ -477,7 +481,7 @@ class LoginFragment: Fragment() {
if (deviceId != null) {
// レスポンスが返ってきたらMainActivity起動
ServerRepository().addServerList()
- whenAuthorizationSucceeds()
+ setCookie()
} else {
LoginUtil.clearAuthStateAndNotificationToken{
requireActivity().runOnUiThread {
@@ -550,15 +554,9 @@ class LoginFragment: Fragment() {
val response = ApiClient.instance.getSession().execute()
if (response.isSuccessful) {
response.body()!!.session_id?.apply {
+ val setCookieHeaders = response.headers().values("Set-Cookie")
val sessionId = response.body()!!.session_id
- setCookie("https://${LoginRepository().loadServerUrl()}", "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None")
- flush()
- // セッションID保存
- var preferences = "cookie" + ServerRepository().loadServer().toString()
- AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE)
- .edit()
- .putString("sessionId", sessionId)
- .apply()
+ SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}")
}
//トークン更新に成功するとメイン画面へ
whenAuthorizationSucceeds()