+44
darkfeed/src/main/kotlin/api/BskyApi.kt
+44
darkfeed/src/main/kotlin/api/BskyApi.kt
···
79
79
}
80
80
},
81
81
) {
82
+
init {
83
+
httpClient.plugin(HttpSend).intercept { request ->
84
+
val originalCall = execute(request)
85
+
86
+
if (originalCall.response.status == HttpStatusCode.BadRequest) {
87
+
val errorResponse = try {
88
+
originalCall.response.body<ErrorResponse>()
89
+
} catch (e: Exception) {
90
+
null
91
+
}
92
+
93
+
if (errorResponse?.error == "ExpiredToken") {
94
+
val currentRefreshToken = bearerTokens.lastOrNull()?.refreshToken ?: return@intercept originalCall
95
+
96
+
@Serializable
97
+
data class Response(val accessJwt: String, val refreshJwt: String)
98
+
99
+
val refreshSessionResponse = httpClient.post("com.atproto.server.refreshSession") {
100
+
header("Authorization", "Bearer $currentRefreshToken")
101
+
}
102
+
103
+
if (refreshSessionResponse.status == HttpStatusCode.OK) {
104
+
val refreshSessionTokens = refreshSessionResponse.body<Response>()
105
+
val newBearerTokens =
106
+
BearerTokens(refreshSessionTokens.accessJwt, refreshSessionTokens.refreshJwt)
107
+
108
+
bearerTokens.addLast(newBearerTokens)
109
+
110
+
val newRequest = HttpRequestBuilder()
111
+
newRequest.takeFrom(request)
112
+
newRequest.headers {
113
+
remove(HttpHeaders.Authorization)
114
+
append(HttpHeaders.Authorization, "Bearer ${newBearerTokens.accessToken}")
115
+
}
116
+
117
+
return@intercept execute(newRequest)
118
+
}
119
+
}
120
+
}
121
+
122
+
originalCall
123
+
}
124
+
}
125
+
82
126
@Serializable
83
127
data class ErrorResponse(
84
128
val error: String,