47 lines
2.0 KiB
Swift
47 lines
2.0 KiB
Swift
import Foundation
|
|
|
|
/// Account-management calls that aren't part of the core auth flow
|
|
/// (`AuthAPI`) — password change and the irreversible delete-account flow.
|
|
enum AccountAPI {
|
|
struct ChangePasswordBody: Encodable {
|
|
let currentPassword: String
|
|
let newPassword: String
|
|
let remember: Bool
|
|
}
|
|
|
|
/// `POST /api/auth/change-password`. On success the backend rotates
|
|
/// EVERY session for the account (including this device's) and issues a
|
|
/// brand-new one — but that new session is delivered as a cookie on the
|
|
/// web path only. For a Bearer client the safest move is to log the user
|
|
/// out locally and have them log back in with the new password, so do
|
|
/// that here rather than trying to recover a token this endpoint doesn't
|
|
/// return.
|
|
static func changePassword(currentPassword: String, newPassword: String) async throws {
|
|
let request = try APIRequest.json(
|
|
path: "/api/auth/change-password",
|
|
method: .post,
|
|
body: ChangePasswordBody(currentPassword: currentPassword, newPassword: newPassword, remember: true)
|
|
)
|
|
try await APIClient.shared.sendDiscardingResponse(request)
|
|
}
|
|
|
|
struct DeleteAccountBody: Encodable {
|
|
let password: String?
|
|
let confirmEmail: String
|
|
}
|
|
|
|
/// `DELETE /api/auth/delete-account`. Irreversible. `password` is
|
|
/// required for accounts that have one (omit only for a Google-only
|
|
/// account, which has no password to check); `confirmEmail` must equal
|
|
/// the account's email exactly, case-sensitively, matching the web
|
|
/// confirmation flow's "type your email to confirm" pattern.
|
|
static func deleteAccount(password: String?, confirmEmail: String) async throws {
|
|
let request = try APIRequest.json(
|
|
path: "/api/auth/delete-account",
|
|
method: .delete,
|
|
body: DeleteAccountBody(password: password, confirmEmail: confirmEmail)
|
|
)
|
|
try await APIClient.shared.sendDiscardingResponse(request)
|
|
}
|
|
}
|