diff --git a/Sources/App/TokenStorage.swift b/Sources/App/TokenStorage.swift new file mode 100644 index 0000000..ae81ab7 --- /dev/null +++ b/Sources/App/TokenStorage.swift @@ -0,0 +1,45 @@ +import Foundation +import BinaryCodable + +struct TokenStorage { + + private(set) var tokens: Set + + private let fileUrl: URL + + private let encoder = BinaryEncoder() + + init(in folder: URL) { + tokens = [] + fileUrl = folder.appendingPathComponent("tokens") + + loadTokensFromDisk() + } + + private mutating func loadTokensFromDisk() { + guard FileManager.default.fileExists(atPath: fileUrl.path) else { + return + } + do { + let data = try Data(contentsOf: fileUrl) + tokens = try BinaryDecoder().decode(from: data) + } catch { + log(error: "Failed to read token file: \(error)") + } + } + + mutating func add(_ tokenUpload: TokenUpload) { + if let oldToken = tokenUpload.previousToken { + tokens.remove(oldToken.hex) + } + tokens.insert(tokenUpload.currentToken.hex) + do { + let data = try encoder.encode(tokens) + try data.write(to: fileUrl) + } catch { + log(error: "Failed to write token file: \(error)") + } + } + +} + diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 4f00e12..664d05b 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -12,12 +12,16 @@ private let apnsEventGroup = MultiThreadedEventLoopGroup(numberOfThreads: System private let apnsRequestEncoder = JSONEncoder() private let apnsResponseDecoder = JSONDecoder() +var tokenStorage: TokenStorage! + // configures your application public func configure(_ app: Application) throws { let resourcesFolderUrl = URL(fileURLWithPath: app.directory.resourcesDirectory) let configUrl = resourcesFolderUrl.appendingPathComponent("config.json") + tokenStorage = .init(in: resourcesFolderUrl) + let config: ServerConfiguration do { let data = try Data(contentsOf: configUrl) @@ -107,6 +111,10 @@ private func configureGPIO(_ config: ServerConfiguration) { } private func sendPush() { + guard !tokenStorage.tokens.isEmpty else { + log(info: "No tokens registered to send push") + return + } Task(priority: .userInitiated) { let client = APNSClient( configuration: apnsConfiguration, @@ -115,7 +123,7 @@ private func sendPush() { requestEncoder: apnsRequestEncoder) log(info: "Client created") do { - for token in knownTokens { + for token in tokenStorage.tokens { log(info: "Sending push to \(token.prefix(6))...") try await client.sendAlertNotification( apnsNotification, diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index 9adbdc6..f4bcbdf 100644 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -6,8 +6,6 @@ private let requestDecoder = BinaryDecoder() var serverStatus: ServerStatus = .starting -var knownTokens = Set() - func routes(_ app: Application) throws { app.post("token") { req async throws -> HTTPResponseStatus in @@ -15,10 +13,7 @@ func routes(_ app: Application) throws { return .badRequest } let tokenUpload: TokenUpload = try requestDecoder.decode(from: data) - if let oldToken = tokenUpload.previousToken { - knownTokens.remove(oldToken.hex) - } - knownTokens.insert(tokenUpload.currentToken.hex) + tokenStorage.add(tokenUpload) return .ok }