fix: decode OAuth token response directly, not via FeishuAPIResponse wrapper
The /authen/v1/oidc/access_token and refresh_access_token endpoints return token fields (access_token, refresh_token, expires_in) at the top level of the JSON response, not nested under a 'data' key like standard Feishu API responses. This caused 'Feishu API error (0): ok' — code 0 with no wrapped data. Changed exchangeCode and refreshAccessToken to decode OAuthTokenData directly from the response. Removed unused decodeAPIResponse helper. Also removed redirect_uri from token exchange body (not required by Feishu's token endpoint). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
74baa22d27
commit
cf9de54792
|
|
@ -51,9 +51,9 @@ final class FeishuAuthService {
|
||||||
request.httpBody = try JSONEncoder().encode([
|
request.httpBody = try JSONEncoder().encode([
|
||||||
"grant_type": "authorization_code",
|
"grant_type": "authorization_code",
|
||||||
"code": code,
|
"code": code,
|
||||||
"redirect_uri": redirectURI,
|
|
||||||
] as [String: String])
|
] as [String: String])
|
||||||
return try await decodeAPIResponse(request)
|
// Token endpoints return data at top level, not wrapped in {code, msg, data}
|
||||||
|
return try await send(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshAccessToken(_ refreshToken: String) async throws -> OAuthTokenData {
|
func refreshAccessToken(_ refreshToken: String) async throws -> OAuthTokenData {
|
||||||
|
|
@ -65,9 +65,10 @@ final class FeishuAuthService {
|
||||||
request.setValue("Bearer \(tenantToken)", forHTTPHeaderField: "Authorization")
|
request.setValue("Bearer \(tenantToken)", forHTTPHeaderField: "Authorization")
|
||||||
request.httpBody = try JSONEncoder().encode([
|
request.httpBody = try JSONEncoder().encode([
|
||||||
"grant_type": "refresh_token",
|
"grant_type": "refresh_token",
|
||||||
"refresh_token": refreshToken
|
"refresh_token": refreshToken,
|
||||||
])
|
] as [String: String])
|
||||||
return try await decodeAPIResponse(request)
|
// Token endpoints return data at top level, not wrapped in {code, msg, data}
|
||||||
|
return try await send(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchCurrentUserName(accessToken: String) async throws -> String {
|
func fetchCurrentUserName(accessToken: String) async throws -> String {
|
||||||
|
|
@ -112,14 +113,6 @@ final class FeishuAuthService {
|
||||||
return data.tenantAccessToken
|
return data.tenantAccessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
private func decodeAPIResponse<T: Decodable>(_ request: URLRequest) async throws -> T {
|
|
||||||
let response: FeishuAPIResponse<T> = try await send(request)
|
|
||||||
guard response.code == 0, let data = response.data else {
|
|
||||||
throw FeishuError.apiError(code: response.code, message: response.msg)
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
private func send<T: Decodable>(_ request: URLRequest) async throws -> T {
|
private func send<T: Decodable>(_ request: URLRequest) async throws -> T {
|
||||||
let (data, response) = try await session.data(for: request)
|
let (data, response) = try await session.data(for: request)
|
||||||
guard let httpResponse = response as? HTTPURLResponse else {
|
guard let httpResponse = response as? HTTPURLResponse else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue