diff --git a/Sources/GoTrue/GoTrueClient.swift b/Sources/GoTrue/GoTrueClient.swift index e992cf2d..b888d7e3 100644 --- a/Sources/GoTrue/GoTrueClient.swift +++ b/Sources/GoTrue/GoTrueClient.swift @@ -609,7 +609,7 @@ public actor GoTrueClient { public func verifyOTP( email: String, token: String, - type: OTPType, + type: EmailOTPType, redirectTo: URL? = nil, captchaToken: String? = nil ) async throws -> AuthResponse { @@ -621,15 +621,17 @@ public actor GoTrueClient { redirectTo.map { URLQueryItem(name: "redirect_to", value: $0.absoluteString) }, ].compactMap { $0 }, body: configuration.encoder.encode( - VerifyOTPParams( - email: email, - token: token, - type: type, - gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)) + VerifyOTPParams.email( + VerifyEmailOTPParams( + email: email, + token: token, + type: type, + gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)) + ) ) ) ), - shouldRemoveSession: type != .emailChange && type != .phoneChange + shouldRemoveSession: type != .emailChange ) } @@ -638,7 +640,7 @@ public actor GoTrueClient { public func verifyOTP( phone: String, token: String, - type: OTPType, + type: MobileOTPType, captchaToken: String? = nil ) async throws -> AuthResponse { try await _verifyOTP( @@ -646,15 +648,17 @@ public actor GoTrueClient { path: "/verify", method: .post, body: configuration.encoder.encode( - VerifyOTPParams( - phone: phone, - token: token, - type: type, - gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)) + VerifyOTPParams.mobile( + VerifyMobileOTPParams( + phone: phone, + token: token, + type: type, + gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)) + ) ) ) ), - shouldRemoveSession: type != .emailChange && type != .phoneChange + shouldRemoveSession: type != .phoneChange ) } diff --git a/Sources/GoTrue/Types.swift b/Sources/GoTrue/Types.swift index f0e2fd59..ffbd16b6 100644 --- a/Sources/GoTrue/Types.swift +++ b/Sources/GoTrue/Types.swift @@ -273,22 +273,47 @@ struct OTPParams: Codable, Hashable, Sendable { var codeChallengeMethod: String? } -struct VerifyOTPParams: Codable, Hashable, Sendable { - var email: String? - var phone: String? +enum VerifyOTPParams: Encodable { + case email(VerifyEmailOTPParams) + case mobile(VerifyMobileOTPParams) + + func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case let .email(value): + try container.encode(value) + case let .mobile(value): + try container.encode(value) + } + } +} + +struct VerifyEmailOTPParams: Encodable, Hashable, Sendable { + var email: String + var token: String + var type: EmailOTPType + var gotrueMetaSecurity: GoTrueMetaSecurity? +} + +struct VerifyMobileOTPParams: Encodable, Hashable { + var phone: String var token: String - var type: OTPType + var type: MobileOTPType var gotrueMetaSecurity: GoTrueMetaSecurity? } -public enum OTPType: String, Codable, CaseIterable, Sendable { +public enum MobileOTPType: String, Encodable, Sendable { case sms case phoneChange = "phone_change" +} + +public enum EmailOTPType: String, Encodable, CaseIterable, Sendable { case signup case invite case magiclink case recovery case emailChange = "email_change" + case email } public enum AuthResponse: Codable, Hashable, Sendable {