diff --git a/Package.swift b/Package.swift index b8ff00e..502db4a 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,6 @@ let package = Package( dependencies: [ .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-beta"), .package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-beta"), - //.package(url: "https://github.com/vapor/toolbox.git", from: "18.0.0-beta"), .package(url: "https://github.com/vapor/apns.git", from: "1.0.0-beta"), .package(url: "https://github.com/apple/swift-log.git", from: "1.0.0") ], diff --git a/Sources/PassKit/PassKit.swift b/Sources/PassKit/PassKit.swift index f9da884..0bf41ae 100644 --- a/Sources/PassKit/PassKit.swift +++ b/Sources/PassKit/PassKit.swift @@ -124,18 +124,33 @@ public class PassKitCustom
whe /// /// - Parameters: /// - middleware: The `Middleware` which will control authentication for the routes. + /// - Throws: An error of type `PassKitError` public func registerPushRoutes(middleware: Middleware) throws { - let privateKeyPath = URL(fileURLWithPath: delegate.pemPrivateKey, relativeTo: delegate.sslSigningFilesDirectory).unixPath() + let privateKeyPath = URL(fileURLWithPath: delegate.pemPrivateKey, relativeTo: + delegate.sslSigningFilesDirectory).unixPath() + + guard FileManager.default.fileExists(atPath: privateKeyPath) else { + throw PassKitError.pemPrivateKeyMissing + } + let pemPath = URL(fileURLWithPath: delegate.pemCertificate, relativeTo: delegate.sslSigningFilesDirectory).unixPath() - + + guard FileManager.default.fileExists(atPath: privateKeyPath) else { + throw PassKitError.pemCertificateMissing + } + // PassKit *only* works with the production APNs. You can't pass in .sandbox here. if app.apns.configuration == nil { - if let pwd = delegate.pemPrivateKeyPassword { - app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger) { - $0(pwd.utf8) + do { + if let pwd = delegate.pemPrivateKeyPassword { + app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger) { + $0(pwd.utf8) + } + } else { + app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger) } - } else { - app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger) + } catch { + throw PassKitError.nioPrivateKeyReadFailed(error) } } @@ -437,10 +452,16 @@ public class PassKitCustom
whe // If the caller's delegate generated a file we don't have to do it. return } - + + let sslBinary = delegate.sslBinary + + guard FileManager.default.fileExists(atPath: sslBinary.unixPath()) else { + throw PassKitError.opensslBinaryMissing + } + let proc = Process() proc.currentDirectoryURL = delegate.sslSigningFilesDirectory - proc.executableURL = delegate.sslBinary + proc.executableURL = sslBinary proc.arguments = [ "smime", "-binary", "-sign", @@ -462,9 +483,14 @@ public class PassKitCustom
whe } private func zip(directory: URL, to: URL) throws { + let zipBinary = delegate.zipBinary + guard FileManager.default.fileExists(atPath: zipBinary.unixPath()) else { + throw PassKitError.zipBinaryMissing + } + let proc = Process() proc.currentDirectoryURL = directory - proc.executableURL = delegate.zipBinary + proc.executableURL = zipBinary proc.arguments = [ to.unixPath(), "-r", "-q", "." ] @@ -472,11 +498,6 @@ public class PassKitCustom
whe
proc.waitUntilExit()
}
- enum PassKitError: Error {
- case templateNotDirectory
- case failedToZipPass
- }
-
private func generatePassContent(for pass: P, on db: Database) -> EventLoopFuture {
let tmp = FileManager.default.temporaryDirectory
let root = tmp.appendingPathComponent(UUID().uuidString, isDirectory: true)
@@ -485,8 +506,12 @@ public class PassKitCustom whe
return delegate.template(for: pass, db: db)
.flatMap { src in
- guard src.hasDirectoryPath else {
- return db.eventLoop.makeFailedFuture(PassKitError.templateNotDirectory)
+ var isDir: ObjCBool = false
+
+ guard src.hasDirectoryPath &&
+ FileManager.default.fileExists(atPath: src.unixPath(), isDirectory: &isDir) &&
+ isDir.boolValue else {
+ return db.eventLoop.makeFailedFuture(PassKitError.templateNotDirectory)
}
return self.delegate.encode(pass: pass, db: db, encoder: encoder)
diff --git a/Sources/PassKit/PassKitError.swift b/Sources/PassKit/PassKitError.swift
new file mode 100644
index 0000000..1aef5ef
--- /dev/null
+++ b/Sources/PassKit/PassKitError.swift
@@ -0,0 +1,28 @@
+//
+// File.swift
+//
+//
+// Created by Scott Grosch on 1/22/20.
+//
+
+import Foundation
+
+public enum PassKitError: Error {
+ /// The template path is not a directory
+ case templateNotDirectory
+
+ /// The `pemCertificate` file is missing.
+ case pemCertificateMissing
+
+ /// The `pemPrivateKey` file is missing.
+ case pemPrivateKeyMissing
+
+ /// Swift NIO failed to read the key.
+ case nioPrivateKeyReadFailed(Error)
+
+ /// The path to the zip binary is incorrect.
+ case zipBinaryMissing
+
+ /// The path to the openssl binary is incorrect
+ case opensslBinaryMissing
+}