Skip to content

Commit

Permalink
fix: Update to user password should persist new sessionToken to Keychain
Browse files Browse the repository at this point in the history
  • Loading branch information
cbaker6 committed Jan 12, 2024
1 parent ca540d5 commit c2d0fc9
Show file tree
Hide file tree
Showing 29 changed files with 506 additions and 327 deletions.
124 changes: 94 additions & 30 deletions Sources/ParseSwift/API/Responses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,93 @@ struct CreateResponse: Decodable {
var updatedAt: Date {
return createdAt
}
var sessionToken: String?

func apply<T>(to object: T) -> T where T: ParseObject {
func setResponseProperties<T>(on object: T) -> T where T: ParseObject {
var object = object
object.objectId = objectId
object.createdAt = createdAt
object.updatedAt = updatedAt
return object
}

func apply<T>(to object: T) -> T where T: ParseObject {
setResponseProperties(on: object)
}

func apply<T>(to user: T) -> T where T: ParseUser {
var user = setResponseProperties(on: user)
user.password = nil
return user
}

}

struct ReplaceResponse: Decodable {
var createdAt: Date?
var updatedAt: Date?
var sessionToken: String?

func apply<T>(to object: T) throws -> T where T: ParseObject {
func setResponseProperties<T>(on object: T) throws -> T where T: ParseObject {
guard let objectId = object.objectId else {
throw ParseError(code: .missingObjectId,
message: "Response from server should not have an objectId of nil")
throw ParseError(
code: .missingObjectId,
message: "Response from server should not have an objectId of nil"
)

Check warning on line 49 in Sources/ParseSwift/API/Responses.swift

View check run for this annotation

Codecov / codecov/patch

Sources/ParseSwift/API/Responses.swift#L46-L49

Added lines #L46 - L49 were not covered by tests
}
guard let createdAt = createdAt else {
guard let updatedAt = updatedAt else {
throw ParseError(code: .otherCause,
message: "Response from server should not have an updatedAt of nil")
throw ParseError(
code: .otherCause,
message: "Response from server should not have an updatedAt of nil"
)
}
return UpdateResponse(updatedAt: updatedAt).apply(to: object)
let response = UpdateResponse(
updatedAt: updatedAt,
sessionToken: sessionToken
).apply(to: object)

return response
}
return CreateResponse(objectId: objectId,
createdAt: createdAt).apply(to: object)
let response = CreateResponse(
objectId: objectId,
createdAt: createdAt,
sessionToken: sessionToken
).apply(to: object)

return response
}

func apply<T>(to object: T) throws -> T where T: ParseObject {
try setResponseProperties(on: object)
}

func apply<T>(to user: T) throws -> T where T: ParseUser {
var user = try setResponseProperties(on: user)
user.password = nil // password should be removed
return user
}
}

struct UpdateResponse: Decodable {
var updatedAt: Date
var sessionToken: String?

func apply<T>(to object: T) -> T where T: ParseObject {
func setResponseProperties<T>(on object: T) -> T where T: ParseObject {
var object = object
object.updatedAt = updatedAt
return object
}
}

struct UpdateSessionTokenResponse: Decodable {
var updatedAt: Date
let sessionToken: String?
func apply<T>(to object: T) -> T where T: ParseObject {
setResponseProperties(on: object)
}

func apply<T>(to user: T) -> T where T: ParseUser {
var user = setResponseProperties(on: user)
user.password = nil // password should be removed
return user
}
}

// MARK: ParseObject Batch
Expand All @@ -70,29 +113,50 @@ struct BatchResponse: Codable {
var objectId: String?
var createdAt: Date?
var updatedAt: Date?
var sessionToken: String?

func asCreateResponse() throws -> CreateResponse {
guard let objectId = objectId else {
throw ParseError(code: .missingObjectId,
message: "Response from server should not have an objectId of nil")
throw ParseError(
code: .missingObjectId,
message: "Response from server should not have an objectId of nil"
)
}
guard let createdAt = createdAt else {
throw ParseError(code: .otherCause,
message: "Response from server should not have an createdAt of nil")
throw ParseError(
code: .otherCause,
message: "Response from server should not have an createdAt of nil"
)
}
return CreateResponse(objectId: objectId, createdAt: createdAt)

let response = CreateResponse(
objectId: objectId,
createdAt: createdAt, sessionToken: sessionToken
)

return response
}

func asReplaceResponse() -> ReplaceResponse {
ReplaceResponse(createdAt: createdAt, updatedAt: updatedAt)
ReplaceResponse(
createdAt: createdAt,
updatedAt: updatedAt,
sessionToken: sessionToken
)
}

func asUpdateResponse() throws -> UpdateResponse {
guard let updatedAt = updatedAt else {
throw ParseError(code: .otherCause,
message: "Response from server should not have an updatedAt of nil")
throw ParseError(
code: .otherCause,
message: "Response from server should not have an updatedAt of nil"
)
}
return UpdateResponse(updatedAt: updatedAt)
let response = UpdateResponse(
updatedAt: updatedAt,
sessionToken: sessionToken
)
return response
}

func apply<T>(to object: T, method: API.Method) throws -> T where T: ParseObject {
Expand Down Expand Up @@ -125,14 +189,14 @@ struct LoginSignupResponse: Codable {
var updatedAt: Date?
let username: String?

func applySignup<T>(to object: T) -> T where T: ParseUser {
var object = object
object.objectId = objectId
object.createdAt = createdAt
object.updatedAt = createdAt
object.password = nil // password should be removed
func apply<T>(to user: T) -> T where T: ParseUser {
var user = user
user.objectId = objectId
user.createdAt = createdAt
user.updatedAt = updatedAt ?? createdAt
user.password = nil // password should be removed

return object
return user
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,8 @@ public extension ParseUser {
return API.Command<Self, Self>(method: .PUT,
path: endpoint,
body: mutableSelf) { (data) -> Self in
let user = try ParseCoding.jsonDecoder().decode(UpdateSessionTokenResponse.self, from: data)
mutableSelf.updatedAt = user.updatedAt
let user = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data)
mutableSelf = user.apply(to: mutableSelf)
if let sessionToken = user.sessionToken {
await Self.setCurrentContainer(.init(currentUser: mutableSelf,
sessionToken: sessionToken))
Expand All @@ -434,9 +434,8 @@ public extension ParseUser {
return API.Command<SignupLoginBody, Self>(method: .PUT,
path: endpoint,
body: body) { (data) -> Self in
let user = try ParseCoding.jsonDecoder().decode(UpdateSessionTokenResponse.self, from: data)
var currentUser = currentStrippedUser
currentUser.updatedAt = user.updatedAt
let user = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data)
var currentUser = user.apply(to: currentStrippedUser)
currentUser.authData = body.authData
if let sessionToken = user.sessionToken {
await Self.setCurrentContainer(.init(currentUser: currentUser,
Expand Down
4 changes: 3 additions & 1 deletion Sources/ParseSwift/Objects/ParseUser+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,9 @@ internal extension ParseUser {
let command: API.Command<Self, Self>!
switch method {
case .save:
command = try await self.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
command = try await self.saveCommand(
ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig
)
case .create:
command = try await self.createCommand()
case .replace:
Expand Down
Loading

0 comments on commit c2d0fc9

Please sign in to comment.