diff --git a/Sources/Auth/Types.swift b/Sources/Auth/Types.swift index a6ea0e7e..d051e4fc 100644 --- a/Sources/Auth/Types.swift +++ b/Sources/Auth/Types.swift @@ -220,6 +220,44 @@ public struct UserIdentity: Codable, Hashable, Identifiable, Sendable { self.lastSignInAt = lastSignInAt self.updatedAt = updatedAt } + + enum CodingKeys: CodingKey { + case id + case identityId + case userId + case identityData + case provider + case createdAt + case lastSignInAt + case updatedAt + } + + public init(from decoder: any Decoder) throws { + let container: KeyedDecodingContainer = try decoder.container(keyedBy: UserIdentity.CodingKeys.self) + + self.id = try container.decode(String.self, forKey: UserIdentity.CodingKeys.id) + self.identityId = try container.decodeIfPresent(UUID.self, forKey: UserIdentity.CodingKeys.identityId) ?? UUID(uuid: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)) + self.userId = try container.decode(UUID.self, forKey: UserIdentity.CodingKeys.userId) + self.identityData = try container.decodeIfPresent([String : AnyJSON].self, forKey: UserIdentity.CodingKeys.identityData) + self.provider = try container.decode(String.self, forKey: UserIdentity.CodingKeys.provider) + self.createdAt = try container.decode(Date.self, forKey: UserIdentity.CodingKeys.createdAt) + self.lastSignInAt = try container.decode(Date.self, forKey: UserIdentity.CodingKeys.lastSignInAt) + self.updatedAt = try container.decode(Date.self, forKey: UserIdentity.CodingKeys.updatedAt) + + } + + public func encode(to encoder: any Encoder) throws { + var container: KeyedEncodingContainer = encoder.container(keyedBy: UserIdentity.CodingKeys.self) + + try container.encode(self.id, forKey: UserIdentity.CodingKeys.id) + try container.encode(self.identityId, forKey: UserIdentity.CodingKeys.identityId) + try container.encode(self.userId, forKey: UserIdentity.CodingKeys.userId) + try container.encodeIfPresent(self.identityData, forKey: UserIdentity.CodingKeys.identityData) + try container.encode(self.provider, forKey: UserIdentity.CodingKeys.provider) + try container.encode(self.createdAt, forKey: UserIdentity.CodingKeys.createdAt) + try container.encode(self.lastSignInAt, forKey: UserIdentity.CodingKeys.lastSignInAt) + try container.encode(self.updatedAt, forKey: UserIdentity.CodingKeys.updatedAt) + } } public enum Provider: String, Identifiable, Codable, CaseIterable, Sendable { diff --git a/Tests/AuthTests/Resources/stored-session_2_4_0.json b/Tests/AuthTests/Resources/stored-session_2_4_0.json new file mode 100644 index 00000000..f2f310ab --- /dev/null +++ b/Tests/AuthTests/Resources/stored-session_2_4_0.json @@ -0,0 +1,40 @@ +{ + "expiration_date": "2022-03-30T10:33:41.018575157Z", + "session": { + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjQ4NjQwMDIxLCJzdWIiOiJmMzNkM2VjOS1hMmVlLTQ3YzQtODBlMS01YmQ5MTlmM2Q4YjgiLCJlbWFpbCI6Imd1aWxoZXJtZTJAZ3Jkcy5kZXYiLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQifQ.4lMvmz2pJkWu1hMsBgXP98Fwz4rbvFYl4VA9joRv6kY", + "token_type": "bearer", + "expires_in": 3600, + "refresh_token": "GGduTeu95GraIXQ56jppkw", + "user": { + "id": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8", + "aud": "authenticated", + "role": "authenticated", + "email": "guilherme@binaryscraping.co", + "email_confirmed_at": "2022-03-30T10:33:41.018575157Z", + "phone": "", + "last_sign_in_at": "2022-03-30T10:33:41.021531328Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email" + ] + }, + "user_metadata": {}, + "identities": [ + { + "id": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8", + "user_id": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8", + "identity_data": { + "sub": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8" + }, + "provider": "email", + "last_sign_in_at": "2022-03-30T10:33:41.015557063Z", + "created_at": "2022-03-30T10:33:41.015612Z", + "updated_at": "2022-03-30T10:33:41.015616Z" + } + ], + "created_at": "2022-03-30T10:33:41.005433Z", + "updated_at": "2022-03-30T10:33:41.022688Z" + } + } +} diff --git a/Tests/AuthTests/Resources/stored-session_2_5_0.json b/Tests/AuthTests/Resources/stored-session_2_5_0.json new file mode 100644 index 00000000..0b557f34 --- /dev/null +++ b/Tests/AuthTests/Resources/stored-session_2_5_0.json @@ -0,0 +1,41 @@ +{ + "expiration_date": "2022-03-30T10:33:41.018575157Z", + "session": { + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjQ4NjQwMDIxLCJzdWIiOiJmMzNkM2VjOS1hMmVlLTQ3YzQtODBlMS01YmQ5MTlmM2Q4YjgiLCJlbWFpbCI6Imd1aWxoZXJtZTJAZ3Jkcy5kZXYiLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQifQ.4lMvmz2pJkWu1hMsBgXP98Fwz4rbvFYl4VA9joRv6kY", + "token_type": "bearer", + "expires_in": 3600, + "refresh_token": "GGduTeu95GraIXQ56jppkw", + "user": { + "id": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8", + "aud": "authenticated", + "role": "authenticated", + "email": "guilherme@binaryscraping.co", + "email_confirmed_at": "2022-03-30T10:33:41.018575157Z", + "phone": "", + "last_sign_in_at": "2022-03-30T10:33:41.021531328Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email" + ] + }, + "user_metadata": {}, + "identities": [ + { + "id": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8", + "user_id": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8", + "identity_id": "859f402d-b3de-4105-a1b9-932836d9193b", + "identity_data": { + "sub": "f33d3ec9-a2ee-47c4-80e1-5bd919f3d8b8" + }, + "provider": "email", + "last_sign_in_at": "2022-03-30T10:33:41.015557063Z", + "created_at": "2022-03-30T10:33:41.015612Z", + "updated_at": "2022-03-30T10:33:41.015616Z" + } + ], + "created_at": "2022-03-30T10:33:41.005433Z", + "updated_at": "2022-03-30T10:33:41.022688Z" + } + } +} diff --git a/Tests/AuthTests/StoredSessionTests.swift b/Tests/AuthTests/StoredSessionTests.swift new file mode 100644 index 00000000..c589bc56 --- /dev/null +++ b/Tests/AuthTests/StoredSessionTests.swift @@ -0,0 +1,19 @@ +@testable import Auth +import SnapshotTesting +import XCTest + +final class StoredSessionTests: XCTestCase { + func testDecode2_4_0() throws { + XCTAssertNoThrow(try AuthClient.Configuration.jsonDecoder.decode( + StoredSession.self, + from: json(named: "stored-session_2_4_0") + )) + } + + func testDecode2_5_0() throws { + XCTAssertNoThrow(try AuthClient.Configuration.jsonDecoder.decode( + StoredSession.self, + from: json(named: "stored-session_2_5_0") + )) + } +}