diff --git a/.gitignore b/.gitignore index 336a128d5..8497f0b61 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,4 @@ fastlane/Preview.html fastlane/screenshots fastlane/test_output +/Shared/Secrets.swift diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index a835e2639..f622a5a2b 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 3B3A33E7238D3D6800314204 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3A33E6238D3D6800314204 /* Secrets.swift */; }; 3B826DA72385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826D9E2385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift */; }; 3B826DA82385C81C00FC1ADB /* FeedWranglerFeedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826D9F2385C81C00FC1ADB /* FeedWranglerFeedItem.swift */; }; 3B826DA92385C81C00FC1ADB /* FeedWranglerAPICaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DA02385C81C00FC1ADB /* FeedWranglerAPICaller.swift */; }; @@ -219,6 +220,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 3B3A33E6238D3D6800314204 /* Secrets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Secrets.swift; path = ../../Shared/Secrets.swift; sourceTree = ""; }; 3B826D9E2385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAuthorizationResult.swift; sourceTree = ""; }; 3B826D9F2385C81C00FC1ADB /* FeedWranglerFeedItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerFeedItem.swift; sourceTree = ""; }; 3B826DA02385C81C00FC1ADB /* FeedWranglerAPICaller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAPICaller.swift; sourceTree = ""; }; @@ -563,6 +565,7 @@ 848934EC1F62484F00CEBD24 = { isa = PBXGroup; children = ( + 3B3A33E6238D3D6800314204 /* Secrets.swift */, 848935101F62486800CEBD24 /* Account.swift */, 841974241F6DDCE4006346C4 /* AccountDelegate.swift */, 51BB7B83233531BC008E8144 /* AccountBehaviors.swift */, @@ -1115,6 +1118,7 @@ 9EAEC62823331C350085D7C9 /* FeedlyCategory.swift in Sources */, 3B826DAE2385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift in Sources */, 9E964EB823754AC400A7AF2E /* OAuthAuthorizationClient+Feedly.swift in Sources */, + 3B3A33E7238D3D6800314204 /* Secrets.swift in Sources */, 9EF1B10923590E93000A486A /* FeedlyStreamIds.swift in Sources */, 84D09623217418DC00D77525 /* FeedbinTagging.swift in Sources */, 84CAD7161FDF2E22000F0755 /* FeedbinEntry.swift in Sources */, diff --git a/Frameworks/Account/FeedWrangler/FeedWranglerConfig.swift b/Frameworks/Account/FeedWrangler/FeedWranglerConfig.swift index 16205707f..24386daab 100644 --- a/Frameworks/Account/FeedWrangler/FeedWranglerConfig.swift +++ b/Frameworks/Account/FeedWrangler/FeedWranglerConfig.swift @@ -10,7 +10,7 @@ import Foundation enum FeedWranglerConfig { static let pageSize = 100 - static let clientKey = "{FEEDWRANGLERKEY}" // Add FEED_WRANGLER_KEY = XYZ to SharedXcodeSettings/DeveloperSettings.xcconfig + static let clientKey = Secrets.FeedWranglerClientKey // Add FEED_WRANGLER_KEY = XYZ to SharedXcodeSettings/DeveloperSettings.xcconfig static let clientPath = "https://feedwrangler.net/api/v2/" static let clientURL = { URL(string: FeedWranglerConfig.clientPath)! diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index a9acae6f3..b25763f28 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -2893,6 +2893,7 @@ isa = PBXNativeTarget; buildConfigurationList = 849C647A1ED37A5D003D8FC0 /* Build configuration list for PBXNativeTarget "NetNewsWire" */; buildPhases = ( + 3B3A341B238D3FB200314204 /* Run Script: Update Secrets */, 51D6803823330CFF0097A009 /* Run Script: Update ArticleExtractorConfig.swift */, 849C645C1ED37A5D003D8FC0 /* Sources */, 517D2D82233A53D600FF3E35 /* Run Script: Reset ArticleExtractorConfig.swift */, @@ -3513,6 +3514,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 3B3A341B238D3FB200314204 /* Run Script: Update Secrets */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Run Script: Update Secrets"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "./updateSecrets.sh\n\n"; + }; 515D50802326D02600EE1167 /* Run Script: Verify No Build Settings */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/Shared/Secrets.swift.gyb b/Shared/Secrets.swift.gyb new file mode 100644 index 000000000..e65f74297 --- /dev/null +++ b/Shared/Secrets.swift.gyb @@ -0,0 +1,37 @@ +// Secrets.swift.gyb +%{ +import os + +def chunks(seq, size): + return (seq[i:(i + size)] for i in range(0, len(seq), size)) + +def encode(string, salt): + bytes = string.encode("UTF-8") + return [ord(bytes[i]) ^ salt[i % len(salt)] for i in range(0, len(bytes))] + +salt = [ord(byte) for byte in os.urandom(64)] +}% +enum Secrets { + + static var FeedWranglerClientKey: String { + let encoded: [UInt8] = [ + % for chunk in chunks(encode(os.environ.get('FEED_WRANGLER_KEY'), salt), 8): + ${"".join(["0x%02x, " % byte for byte in chunk])} + % end + ] + + return decode(encoded, salt: salt) + } + + private static let salt: [UInt8] = [ + % for chunk in chunks(salt, 8): + ${"".join(["0x%02x, " % byte for byte in chunk])} + % end + ] + + private static func decode(_ encoded: [UInt8], salt: [UInt8]) -> String { + String(decoding: encoded.enumerated().map { (offset, element) in + element ^ salt[offset % salt.count] + }, as: UTF8.self) + } +} \ No newline at end of file diff --git a/updateSecrets.sh b/updateSecrets.sh new file mode 100755 index 000000000..d5fa38cc9 --- /dev/null +++ b/updateSecrets.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +find . -name '*.gyb' | \ + while read file; do \ + echo "running ${file%.gyb}"; \ + gyb --line-directive '' -o "${file%.gyb}" "$file"; \ + done \ No newline at end of file