TM-SGNL-iOS/SignalServiceKit/Util/MailtoLink.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

66 lines
2 KiB
Swift

//
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
/// A pretty basic mailto: link builder
public struct MailtoLink {
public var recipients: [String] = []
public var ccRecipients: [String] = []
public var bccRecipients: [String] = []
public var subject: String
public var body: String
public init(to recipient: String, subject: String, body: String) {
self.init(to: [recipient], subject: subject, body: body)
}
public init(to recipients: [String], subject: String, body: String) {
self.recipients = recipients
self.subject = subject
self.body = body
}
public var url: URL? {
let componentsBuilder = NSURLComponents()
componentsBuilder.scheme = "mailto"
componentsBuilder.percentEncodedPath = escapeList(recipients)
let rawQueryItems = [
("cc", escapeList(ccRecipients)),
("bcc", escapeList(bccRecipients)),
("subject", escapeString(subject)),
("body", escapeString(body))
]
let cleanedQueryItems = rawQueryItems
.filter { !$0.1.isEmpty }
.map { URLQueryItem(name: $0.0, value: $0.1) }
componentsBuilder.percentEncodedQueryItems = cleanedQueryItems
return componentsBuilder.url
}
// MARK: - Private
private let allowableCharacters: CharacterSet = {
var validChars = CharacterSet.urlPathAllowed
// explicitly disallowed by RFC 6068
validChars.remove(charactersIn: "%/?#[]&;=")
// also drop commas and newlines for simplicity
validChars.remove(charactersIn: ",\n")
return validChars
}()
private func escapeString(_ string: String) -> String {
return string.addingPercentEncoding(withAllowedCharacters: allowableCharacters) ?? ""
}
private func escapeList(_ list: [String]) -> String {
return list
.compactMap { escapeString($0) }
.joined(separator: ",")
}
}