// // PushSubscription.swift // Pachyderm // // Created by Shadowfacts on 9/9/18. // Copyright © 2018 Shadowfacts. All rights reserved. // import Foundation public struct PushSubscription: Decodable, Sendable { public let id: String public let endpoint: URL public let serverKey: String public let alerts: Alerts public let policy: Policy public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // id is documented as being a string, but mastodon returns a json number if let s = try? container.decode(String.self, forKey: .id) { self.id = s } else { let i = try container.decode(Int.self, forKey: .id) self.id = i.description } self.endpoint = try container.decode(URL.self, forKey: .endpoint) self.serverKey = try container.decode(String.self, forKey: .serverKey) self.alerts = try container.decode(PushSubscription.Alerts.self, forKey: .alerts) self.policy = try container.decode(PushSubscription.Policy.self, forKey: .policy) } public static func create(endpoint: URL, publicKey: Data, authSecret: Data, alerts: Alerts, policy: Policy) -> Request { return Request(method: .post, path: "/api/v1/push/subscription", body: ParametersBody([ "subscription[endpoint]" => endpoint.absoluteString, "subscription[keys][p256dh]" => publicKey.base64EncodedString(), "subscription[keys][auth]" => authSecret.base64EncodedString(), "data[alerts][mention]" => alerts.mention, "data[alerts][status]" => alerts.status, "data[alerts][reblog]" => alerts.reblog, "data[alerts][follow]" => alerts.follow, "data[alerts][follow_request]" => alerts.followRequest, "data[alerts][favourite]" => alerts.favourite, "data[alerts][poll]" => alerts.poll, "data[alerts][update]" => alerts.update, "data[policy]" => policy.rawValue, ])) } public static func update(alerts: Alerts, policy: Policy) -> Request { return Request(method: .put, path: "/api/v1/push/subscription", body: ParametersBody([ "data[alerts][mention]" => alerts.mention, "data[alerts][status]" => alerts.status, "data[alerts][reblog]" => alerts.reblog, "data[alerts][follow]" => alerts.follow, "data[alerts][follow_request]" => alerts.followRequest, "data[alerts][favourite]" => alerts.favourite, "data[alerts][poll]" => alerts.poll, "data[alerts][update]" => alerts.update, "data[policy]" => policy.rawValue, ])) } public static func delete() -> Request { return Request(method: .delete, path: "/api/v1/push/subscription") } private enum CodingKeys: String, CodingKey { case id case endpoint case serverKey = "server_key" case alerts case policy } } extension PushSubscription { public struct Alerts: Decodable, Sendable { public let mention: Bool public let status: Bool public let reblog: Bool public let follow: Bool public let followRequest: Bool public let favourite: Bool public let poll: Bool public let update: Bool public init(mention: Bool, status: Bool, reblog: Bool, follow: Bool, followRequest: Bool, favourite: Bool, poll: Bool, update: Bool) { self.mention = mention self.status = status self.reblog = reblog self.follow = follow self.followRequest = followRequest self.favourite = favourite self.poll = poll self.update = update } private enum CodingKeys: String, CodingKey { case mention case status case reblog case follow case followRequest = "follow_request" case favourite case poll case update } } } extension PushSubscription { public enum Policy: String, Decodable, Sendable { case all case followed case followers case none } }