Skip to content

Commit

Permalink
fix(auth): stored session backwards compatibility (#294)
Browse files Browse the repository at this point in the history
* Adds (failing) test for stored session decoding

* Provides default value to `identityId`

* style: swift format

---------

Co-authored-by: leoMehlig <[email protected]>
  • Loading branch information
grdsdev and leoMehlig authored Apr 1, 2024
1 parent 7ef5223 commit 847fe97
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Sources/Auth/Internal/SessionStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ struct StoredSession: Codable {

init(session: Session, expirationDate: Date? = nil) {
self.session = session
self.expirationDate = expirationDate ?? Date().addingTimeInterval(session.expiresIn)
self.expirationDate = expirationDate
?? session.expiresAt.map(Date.init(timeIntervalSince1970:))
?? Date().addingTimeInterval(session.expiresIn)
}
}

Expand Down
38 changes: 38 additions & 0 deletions Sources/Auth/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,44 @@ public struct UserIdentity: Codable, Hashable, Identifiable, Sendable {
self.lastSignInAt = lastSignInAt
self.updatedAt = updatedAt
}

private 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 = try decoder.container(keyedBy: CodingKeys.self)

id = try container.decode(String.self, forKey: .id)
identityId = try container.decodeIfPresent(UUID.self, forKey: .identityId)
?? UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
userId = try container.decode(UUID.self, forKey: .userId)
identityData = try container.decodeIfPresent([String: AnyJSON].self, forKey: .identityData)
provider = try container.decode(String.self, forKey: .provider)
createdAt = try container.decode(Date.self, forKey: .createdAt)
lastSignInAt = try container.decode(Date.self, forKey: .lastSignInAt)
updatedAt = try container.decode(Date.self, forKey: .updatedAt)
}

public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(id, forKey: .id)
try container.encode(identityId, forKey: .identityId)
try container.encode(userId, forKey: .userId)
try container.encodeIfPresent(identityData, forKey: .identityData)
try container.encode(provider, forKey: .provider)
try container.encode(createdAt, forKey: .createdAt)
try container.encode(lastSignInAt, forKey: .lastSignInAt)
try container.encode(updatedAt, forKey: .updatedAt)
}
}

public enum Provider: String, Identifiable, Codable, CaseIterable, Sendable {
Expand Down
1 change: 1 addition & 0 deletions Tests/AuthTests/AuthClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ final class AuthClientTests: XCTestCase {

override func setUp() {
super.setUp()
Current = .mock

eventEmitter = .mock
sessionManager = .mock
Expand Down
2 changes: 1 addition & 1 deletion Tests/AuthTests/MockHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ func json(named name: String) -> Data {

extension Decodable {
init(fromMockNamed name: String) {
self = try! AuthClient.Configuration.jsonDecoder.decode(Self.self, from: json(named: name))
self = try! Current.configuration.decoder.decode(Self.self, from: json(named: name))
}
}
40 changes: 40 additions & 0 deletions Tests/AuthTests/Resources/stored-session_2_4_0.json
Original file line number Diff line number Diff line change
@@ -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": "[email protected]",
"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"
}
}
}
41 changes: 41 additions & 0 deletions Tests/AuthTests/Resources/stored-session_2_5_0.json
Original file line number Diff line number Diff line change
@@ -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": "[email protected]",
"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"
}
}
}
19 changes: 19 additions & 0 deletions Tests/AuthTests/StoredSessionTests.swift
Original file line number Diff line number Diff line change
@@ -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")
))
}
}

0 comments on commit 847fe97

Please sign in to comment.