diff --git a/Jared.xcodeproj/project.pbxproj b/Jared.xcodeproj/project.pbxproj index 137c58a..309ae88 100644 --- a/Jared.xcodeproj/project.pbxproj +++ b/Jared.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 00FC0A452FD8C8D0FCDA16D4 /* Pods_Jared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4589B5638BC576CC8AB2700A /* Pods_Jared.framework */; }; 1D6188C0EEA4AA406C15CC9E /* Pods_Jared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4589B5638BC576CC8AB2700A /* Pods_Jared.framework */; }; 7F0E931D1D02FC250096BABE /* Global.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0E931C1D02FC250096BABE /* Global.swift */; }; 7F84B6221CC506790059A82B /* JaredFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F84B6211CC506790059A82B /* JaredFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -31,9 +32,10 @@ B37E82821FA85B210069E15D /* SendTextSingleBuddy.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B37E82811FA85B210069E15D /* SendTextSingleBuddy.scpt */; }; B39A65E01CC1FB1B003E26B0 /* Routing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39A65DF1CC1FB1B003E26B0 /* Routing.swift */; }; B39F2B391CB3BCA700C0D35C /* SendText.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B39F2B381CB3BCA700C0D35C /* SendText.scpt */; }; - B3AECB5E2207CE2C003E32F8 /* Pods_Jared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4589B5638BC576CC8AB2700A /* Pods_Jared.framework */; }; + B3A4C61423B867E300B7F009 /* MessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3A4C61323B867E300B7F009 /* MessageRequest.swift */; }; B3AECB5F2207CE33003E32F8 /* JaredFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F84B61F1CC506790059A82B /* JaredFramework.framework */; }; B3BBA7D11CB3284A00E1749C /* CoreModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39EC17D1CB01FEF002C3161 /* CoreModule.swift */; }; + B3C59284224DD17900116ECB /* JaredWebServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C59283224DD17900116ECB /* JaredWebServer.swift */; }; B3EF1DA02206849000953DE7 /* WebHookManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3327DC522066427009DD882 /* WebHookManager.swift */; }; B3EF1DA4220687DD00953DE7 /* URLProtocolMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EF1DA3220687DD00953DE7 /* URLProtocolMock.swift */; }; B3EF1DA62206DFEA00953DE7 /* Route.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EF1DA52206DFEA00953DE7 /* Route.swift */; }; @@ -116,9 +118,11 @@ B39EC1751CB01F55002C3161 /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Message.swift; path = ../Jared/Message.swift; sourceTree = ""; }; B39EC17D1CB01FEF002C3161 /* CoreModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreModule.swift; sourceTree = ""; }; B39F2B381CB3BCA700C0D35C /* SendText.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = SendText.scpt; sourceTree = ""; }; + B3A4C61323B867E300B7F009 /* MessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRequest.swift; sourceTree = ""; }; B3BBA7CC1CB3259A00E1749C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/CoreStrings.strings; sourceTree = ""; }; B3BBA7CF1CB327C200E1749C /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = ""; }; B3BBA7D01CB327C200E1749C /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/CoreStrings.strings; sourceTree = ""; }; + B3C59283224DD17900116ECB /* JaredWebServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JaredWebServer.swift; sourceTree = ""; }; B3EF1DA3220687DD00953DE7 /* URLProtocolMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLProtocolMock.swift; sourceTree = ""; }; B3EF1DA52206DFEA00953DE7 /* Route.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Route.swift; sourceTree = ""; }; B3EF1DA92206E09B00953DE7 /* Jared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Jared.swift; sourceTree = ""; }; @@ -143,6 +147,7 @@ files = ( 7F84B6261CC506790059A82B /* JaredFramework.framework in Frameworks */, 1D6188C0EEA4AA406C15CC9E /* Pods_Jared.framework in Frameworks */, + 00FC0A452FD8C8D0FCDA16D4 /* Pods_Jared.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -151,7 +156,6 @@ buildActionMask = 2147483647; files = ( B3AECB5F2207CE33003E32F8 /* JaredFramework.framework in Frameworks */, - B3AECB5E2207CE2C003E32F8 /* Pods_Jared.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -262,6 +266,8 @@ B39A65DF1CC1FB1B003E26B0 /* Routing.swift */, B3327DC522066427009DD882 /* WebHookManager.swift */, B3327DC32206607B009DD882 /* ContactHelper.swift */, + B3C59283224DD17900116ECB /* JaredWebServer.swift */, + B3A4C61323B867E300B7F009 /* MessageRequest.swift */, B35CE7142196AD4E002F52A7 /* DatabaseHandler.swift */, 7F0E931C1D02FC250096BABE /* Global.swift */, B3BBA7CD1CB3259A00E1749C /* CoreStrings.strings */, @@ -369,6 +375,7 @@ TargetAttributes = { 7F84B61E1CC506790059A82B = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = C7LJ587XF3; LastSwiftMigration = 1010; ProvisioningStyle = Automatic; }; @@ -447,13 +454,19 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-Jared/Pods-Jared-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/CocoaAsyncSocket/CocoaAsyncSocket.framework", + "${BUILT_PRODUCTS_DIR}/HTTPParserC/HTTPParserC.framework", "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${BUILT_PRODUCTS_DIR}/Telegraph/Telegraph.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaAsyncSocket.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HTTPParserC.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Telegraph.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -529,6 +542,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B3A4C61423B867E300B7F009 /* MessageRequest.swift in Sources */, B39A65E01CC1FB1B003E26B0 /* Routing.swift in Sources */, B3BBA7D11CB3284A00E1749C /* CoreModule.swift in Sources */, B36563EF1F3D68980064B114 /* TouchBarTextFieldExtension.swift in Sources */, @@ -540,6 +554,7 @@ B316D1A61F3FFDF100AFF063 /* CoreModuleRealm.swift in Sources */, B375A65921EB14470073F09F /* AboutViewController.swift in Sources */, 7F0E931D1D02FC250096BABE /* Global.swift in Sources */, + B3C59284224DD17900116ECB /* JaredWebServer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -604,7 +619,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = C7LJ587XF3; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -630,7 +645,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = C7LJ587XF3; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; diff --git a/Jared.xcodeproj/xcshareddata/xcschemes/JaredFramework.xcscheme b/Jared.xcodeproj/xcshareddata/xcschemes/JaredFramework.xcscheme index 8c2612b..6bedc53 100644 --- a/Jared.xcodeproj/xcshareddata/xcschemes/JaredFramework.xcscheme +++ b/Jared.xcodeproj/xcshareddata/xcschemes/JaredFramework.xcscheme @@ -33,7 +33,7 @@ Int { + let filemanager = FileManager.default + let appsupport = filemanager.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] + let supportDir = appsupport.appendingPathComponent("Jared") + let configPath = supportDir.appendingPathComponent("config.json") + do { + // If config file does not exist, use default port + guard filemanager.fileExists(atPath: configPath.path) else { + return JaredWebServer.DEFAULT_PORT + } + + //Read the JSON config file + let jsonData = try! NSData(contentsOfFile: supportDir.appendingPathComponent("config.json").path, options: .mappedIfSafe) + + // If the JSON format is not as expected at all, use the default port + guard let jsonResult = try? JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:AnyObject] else { + return JaredWebServer.DEFAULT_PORT + } + + guard let serverConfig = jsonResult?["webserver"] as? [String : AnyObject] else { + return JaredWebServer.DEFAULT_PORT + } + + guard let configPort = serverConfig["port"] as? NSNumber else { + return JaredWebServer.DEFAULT_PORT + } + + return Int(truncating: configPort) + } + } + + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + if (keyPath == "RestApiIsDisabled") { + updateServerState() + } + } + + func updateServerState() { + if (defaults.bool(forKey: "RestApiIsDisabled")) { + stop() + } else { + start() + } + } + + func start() { + try? server.start(port: port) + } + + func stop() { + server.stop() + } + + static func handleMessageRequest(request: HTTPRequest) -> HTTPResponse { + // Attempt to decode the request body to the MessageRequest struct + do { + let parsedBody = try JSONDecoder().decode(MessageRequest.self, from: request.body) + + if let textBody = parsedBody.body as? TextBody { + Jared.Send(textBody.message, to: parsedBody.recipient) + return HTTPResponse() + } + else { + return HTTPResponse(HTTPStatus(code: 400, phrase: "Bad Request"), headers: HTTPHeaders(), content: "Image body types are not supported yet.") + } + } catch { + return HTTPResponse(HTTPStatus(code: 400, phrase: "Bad Request"), headers: HTTPHeaders(), content: error.localizedDescription) + } + } +} + + diff --git a/Jared/MessageRequest.swift b/Jared/MessageRequest.swift new file mode 100644 index 0000000..56ead4a --- /dev/null +++ b/Jared/MessageRequest.swift @@ -0,0 +1,45 @@ +// +// MessageRequest.swift +// Jared +// +// Created by Zeke Snider on 12/28/19. +// Copyright © 2019 Zeke Snider. All rights reserved. +// + +import Foundation +import JaredFramework + +// Struct that defines what parameters are accepted in requests +public struct MessageRequest: Decodable { + public var body: MessageBody + public var recipient: RecipientEntity + + enum CodingKeys : String, CodingKey { + case body + case recipient + } + + enum ParameterError: Error { + case runtimeError(String) + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + if let textBody = try? container.decode(TextBody.self, forKey: .body) { + self.body = textBody + } else if let imageBody = try? container.decode(ImageBody.self, forKey: .body) { + self.body = imageBody + } else { + throw ParameterError.runtimeError("the body parameter is incorrectly formatted") + } + + if let person = try? container.decode(Person.self, forKey: .recipient) { + self.recipient = person + } else if let group = try? container.decode(Group.self, forKey: .recipient) { + self.recipient = group + } else { + throw ParameterError.runtimeError("the recipient parameter is incorrectly formatted") + } + } +} diff --git a/Jared/config.json b/Jared/config.json index 9b89e99..5bd332d 100644 --- a/Jared/config.json +++ b/Jared/config.json @@ -2,5 +2,8 @@ "routes": { }, "webhooks": [ - ] + ], + "webserver": { + "port": 3000 + } } diff --git a/JaredFramework/Bodies.swift b/JaredFramework/Bodies.swift index 8200b62..d90d036 100644 --- a/JaredFramework/Bodies.swift +++ b/JaredFramework/Bodies.swift @@ -13,8 +13,8 @@ public protocol MessageBody: Codable {} public struct TextBody: MessageBody, Codable { public var message: String - public init(_ inMessage: String) { - message = inMessage + public init(_ message: String) { + self.message = message } } diff --git a/JaredFramework/Entities.swift b/JaredFramework/Entities.swift index c56c791..62e1773 100644 --- a/JaredFramework/Entities.swift +++ b/JaredFramework/Entities.swift @@ -21,10 +21,18 @@ public struct Person: SenderEntity, RecipientEntity, Codable, Equatable { public var handle: String public var isMe: Bool = false - public init(givenName: String?, handle: String, isMe: Bool) { + enum CodingKeys : String, CodingKey{ + case handle + } + + public init(handle: String) { + self.handle = handle + } + + public init(givenName: String?, handle: String, isMe: Bool?) { self.givenName = givenName self.handle = handle - self.isMe = isMe + self.isMe = isMe ?? false } public static func == (lhs: Person, rhs: Person) -> Bool { diff --git a/JaredFramework/Info.plist b/JaredFramework/Info.plist index 01c96ce..1b49f36 100644 --- a/JaredFramework/Info.plist +++ b/JaredFramework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0 + 2.1 CFBundleSignature ???? CFBundleVersion diff --git a/JaredUI/AboutViewController.swift b/JaredUI/AboutViewController.swift index 8fcb3bc..825bede 100644 --- a/JaredUI/AboutViewController.swift +++ b/JaredUI/AboutViewController.swift @@ -9,7 +9,6 @@ import Cocoa class AboutViewController: NSViewController { - @IBAction func updateButtonClicked(_ sender: Any) { NSWorkspace.shared.open(URL(string: "https://github.com/zekesnider/jared/releases")!) } diff --git a/JaredUI/AppDelegate.swift b/JaredUI/AppDelegate.swift index 856a016..7f9957f 100644 --- a/JaredUI/AppDelegate.swift +++ b/JaredUI/AppDelegate.swift @@ -11,8 +11,8 @@ import Contacts @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - var Router = MessageRouting() + var Server = JaredWebServer() func applicationDidFinishLaunching(_ aNotification: Notification) { // If this is the first run of the application, request access diff --git a/JaredUI/Base.lproj/Main.storyboard b/JaredUI/Base.lproj/Main.storyboard index 5bfde97..2ae4908 100644 --- a/JaredUI/Base.lproj/Main.storyboard +++ b/JaredUI/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - - + + @@ -175,18 +175,18 @@ - + - + - Copyright © 2016–2019 Zeke Snider. + Copyright © 2016–2020 Zeke Snider. All rights reserved. @@ -241,7 +241,7 @@ All rights reserved. - + - + - + @@ -301,6 +301,34 @@ All rights reserved. + + + + + + + + + + + + + + + + + + @@ -312,8 +340,8 @@ All rights reserved. -