Skip to content

Commit 3bd8287

Browse files
committed
Polish API naming: remove SSH prefixes across module
1 parent 69ccf92 commit 3bd8287

36 files changed

Lines changed: 496 additions & 496 deletions

Examples/E2E/main.swift

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ struct CloudflaredE2ECLI {
1515
case serviceToken = "2"
1616
}
1717

18-
private struct ManualOAuthFlow: SSHOAuthFlow {
18+
private struct ManualOAuthFlow: OAuthFlow {
1919
func fetchToken(teamDomain: String, appDomain: String, callbackScheme: String, hostname: String) async throws -> String {
20-
let originURL = try SSHURLTools.normalizeOriginURL(from: hostname)
20+
let originURL = try URLTools.normalizeOriginURL(from: hostname)
2121

2222
print("")
2323
print("Open this protected app URL in your browser and complete Cloudflare Access login:")
@@ -30,7 +30,7 @@ struct CloudflaredE2ECLI {
3030
.trimmingCharacters(in: .whitespacesAndNewlines)
3131

3232
guard !token.isEmpty else {
33-
throw SSHFailure.auth("oauth token input was empty")
33+
throw Failure.auth("oauth token input was empty")
3434
}
3535

3636
return token
@@ -40,7 +40,7 @@ struct CloudflaredE2ECLI {
4040
static func main() async {
4141
do {
4242
try await run()
43-
} catch let failure as SSHFailure {
43+
} catch let failure as Failure {
4444
fputs("Error: \(failure)\n", stderr)
4545
Foundation.exit(1)
4646
} catch {
@@ -56,14 +56,14 @@ struct CloudflaredE2ECLI {
5656
let hostname = try promptRequired("Cloudflare-protected hostname (e.g. ssh.example.com): ")
5757
let authChoice = try promptAuthChoice()
5858

59-
let authProvider: any SSHAuthProviding
60-
let method: SSHAuthMethod
59+
let authProvider: any AuthProviding
60+
let method: AuthMethod
6161

6262
switch authChoice {
6363
case .oauth:
64-
let oauthProvider = SSHOAuthProvider(
64+
let oauthProvider = OAuthProvider(
6565
flow: ManualOAuthFlow(),
66-
tokenStore: SSHInMemoryTokenStore()
66+
tokenStore: InMemoryTokenStore()
6767
)
6868
authProvider = oauthProvider
6969
method = try await resolveOAuthMethod(hostname: hostname)
@@ -72,14 +72,14 @@ struct CloudflaredE2ECLI {
7272
let clientID = try promptRequired("Service token client ID: ")
7373
let clientSecret = try promptSecretRequired("Service token client secret: ")
7474

75-
authProvider = SSHServiceTokenProvider()
75+
authProvider = ServiceTokenProvider()
7676
method = .serviceToken(teamDomain: "local", clientID: clientID, clientSecret: clientSecret)
7777
}
7878

79-
let session = SSHSessionActor(
79+
let session = SessionActor(
8080
authProvider: authProvider,
81-
tunnelProvider: SSHCloudflareTunnelProvider(),
82-
retryPolicy: SSHRetryPolicy(maxReconnectAttempts: 2, baseDelayNanoseconds: 500_000_000),
81+
tunnelProvider: CloudflareTunnelProvider(),
82+
retryPolicy: RetryPolicy(maxReconnectAttempts: 2, baseDelayNanoseconds: 500_000_000),
8383
oauthFallback: nil,
8484
sleep: { delay in
8585
try? await Task.sleep(nanoseconds: delay)
@@ -120,19 +120,19 @@ struct CloudflaredE2ECLI {
120120
stateTask.cancel()
121121
}
122122

123-
private struct URLSessionHTTPClient: SSHHTTPClient {
123+
private struct URLSessionHTTPClient: HTTPClient {
124124
func send(_ request: URLRequest) async throws -> (Data, HTTPURLResponse) {
125125
let (data, response) = try await URLSession.shared.data(for: request)
126126
guard let http = response as? HTTPURLResponse else {
127-
throw SSHFailure.protocolViolation("non-http response while resolving app info")
127+
throw Failure.protocolViolation("non-http response while resolving app info")
128128
}
129129
return (data, http)
130130
}
131131
}
132132

133-
private static func resolveOAuthMethod(hostname: String) async throws -> SSHAuthMethod {
134-
let originURL = try SSHURLTools.normalizeOriginURL(from: hostname)
135-
let resolver = SSHAppInfoResolver(client: URLSessionHTTPClient(), userAgent: "cloudflared-e2e")
133+
private static func resolveOAuthMethod(hostname: String) async throws -> AuthMethod {
134+
let originURL = try URLTools.normalizeOriginURL(from: hostname)
135+
let resolver = AppInfoResolver(client: URLSessionHTTPClient(), userAgent: "cloudflared-e2e")
136136

137137
if let appInfo = try? await resolver.resolve(appURL: originURL) {
138138
return .oauth(
@@ -149,7 +149,7 @@ struct CloudflaredE2ECLI {
149149
)
150150
}
151151

152-
private static func describe(_ state: SSHConnectionState) -> String {
152+
private static func describe(_ state: ConnectionState) -> String {
153153
switch state {
154154
case .idle:
155155
return "idle"
@@ -227,7 +227,7 @@ struct CloudflaredE2ECLI {
227227
private static func runTunnelProbe(localPort: UInt16) throws -> ProbeResult {
228228
let fd = socket(AF_INET, SOCK_STREAM, 0)
229229
guard fd >= 0 else {
230-
throw SSHFailure.transport("probe failed to create socket", retryable: true)
230+
throw Failure.transport("probe failed to create socket", retryable: true)
231231
}
232232
defer { _ = close(fd) }
233233

@@ -240,7 +240,7 @@ struct CloudflaredE2ECLI {
240240

241241
let pton = "127.0.0.1".withCString { inet_pton(AF_INET, $0, &address.sin_addr) }
242242
guard pton == 1 else {
243-
throw SSHFailure.transport("probe failed to encode loopback", retryable: false)
243+
throw Failure.transport("probe failed to encode loopback", retryable: false)
244244
}
245245

246246
let connectResult = withUnsafePointer(to: &address) {
@@ -249,7 +249,7 @@ struct CloudflaredE2ECLI {
249249
}
250250
}
251251
guard connectResult == 0 else {
252-
throw SSHFailure.transport("probe failed to connect to local tunnel", retryable: true)
252+
throw Failure.transport("probe failed to connect to local tunnel", retryable: true)
253253
}
254254

255255
var timeout = timeval(tv_sec: 2, tv_usec: 0)
@@ -266,7 +266,7 @@ struct CloudflaredE2ECLI {
266266
}
267267

268268
if count == 0 {
269-
throw SSHFailure.transport(
269+
throw Failure.transport(
270270
"probe socket closed immediately; Cloudflare auth/upstream connection likely failed",
271271
retryable: false
272272
)
@@ -276,6 +276,6 @@ struct CloudflaredE2ECLI {
276276
return .openWithoutData
277277
}
278278

279-
throw SSHFailure.transport("probe recv failed with errno \(errno)", retryable: true)
279+
throw Failure.transport("probe recv failed with errno \(errno)", retryable: true)
280280
}
281281
}

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ Then add the library target:
5353
```swift
5454
import Cloudflared
5555

56-
let session = SSHSessionActor(
57-
authProvider: SSHServiceTokenProvider(),
58-
tunnelProvider: SSHCloudflareTunnelProvider(),
59-
retryPolicy: SSHRetryPolicy(maxReconnectAttempts: 2, baseDelayNanoseconds: 500_000_000),
56+
let session = SessionActor(
57+
authProvider: ServiceTokenProvider(),
58+
tunnelProvider: CloudflareTunnelProvider(),
59+
retryPolicy: RetryPolicy(maxReconnectAttempts: 2, baseDelayNanoseconds: 500_000_000),
6060
oauthFallback: nil,
6161
sleep: { delay in try? await Task.sleep(nanoseconds: delay) }
6262
)
@@ -76,12 +76,12 @@ print("Tunnel endpoint: 127.0.0.1:\(localPort)")
7676

7777
## OAuth Flow Integration
7878

79-
OAuth UI/token acquisition is app-owned via `SSHOAuthFlow`:
79+
OAuth UI/token acquisition is app-owned via `OAuthFlow`:
8080

8181
```swift
8282
import Cloudflared
8383

84-
struct MyOAuthFlow: SSHOAuthFlow {
84+
struct MyOAuthFlow: OAuthFlow {
8585
func fetchToken(
8686
teamDomain: String,
8787
appDomain: String,
@@ -90,17 +90,17 @@ struct MyOAuthFlow: SSHOAuthFlow {
9090
) async throws -> String {
9191
// Implement your Access login UX (for example ASWebAuthenticationSession)
9292
// and return CF_Authorization JWT.
93-
throw SSHFailure.auth("not implemented")
93+
throw Failure.auth("not implemented")
9494
}
9595
}
9696

97-
let oauthProvider = SSHOAuthProvider(
97+
let oauthProvider = OAuthProvider(
9898
flow: MyOAuthFlow(),
99-
tokenStore: SSHKeychainTokenStore()
99+
tokenStore: KeychainTokenStore()
100100
)
101101
```
102102

103-
For app metadata discovery (`authDomain`, `appDomain`, `appAUD`) you can use `SSHAppInfoResolver`.
103+
For app metadata discovery (`authDomain`, `appDomain`, `appAUD`) you can use `AppInfoResolver`.
104104

105105
## State Stream
106106

@@ -131,34 +131,34 @@ Example runtime mapping:
131131

132132
## Token Storage Customization
133133

134-
If you need your own keychain layout or storage backend, implement `SSHTokenStore`:
134+
If you need your own keychain layout or storage backend, implement `TokenStore`:
135135

136136
```swift
137137
import Cloudflared
138138

139-
actor CustomTokenStore: SSHTokenStore {
139+
actor CustomTokenStore: TokenStore {
140140
func readToken(for key: String) async throws -> String? { nil }
141141
func writeToken(_ token: String, for key: String) async throws {}
142142
func removeToken(for key: String) async throws {}
143143
}
144144
```
145145

146-
Then inject it into `SSHOAuthProvider`.
146+
Then inject it into `OAuthProvider`.
147147

148-
`SSHKeychainTokenStore` defaults:
148+
`KeychainTokenStore` defaults:
149149
- iOS/tvOS/watchOS: `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`
150150
- macOS: `kSecAttrAccessibleAfterFirstUnlock` + data-protection keychain mode
151151

152152
## Local Security Defaults
153153

154-
`SSHCloudflareTunnelProvider` defaults to:
154+
`CloudflareTunnelProvider` defaults to:
155155
- `maxConcurrentConnections = 1`
156156
- `stopAcceptingAfterFirstConnection = true`
157157

158158
You can override via:
159159

160160
```swift
161-
let tunnel = SSHCloudflareTunnelProvider(
161+
let tunnel = CloudflareTunnelProvider(
162162
connectionLimits: .init(
163163
maxConcurrentConnections: 2,
164164
stopAcceptingAfterFirstConnection: false
@@ -193,7 +193,7 @@ swift build
193193
Optional keychain integration test:
194194

195195
```bash
196-
CLOUDFLARED_KEYCHAIN_TESTS=1 swift test --filter SSHTokenStoreTests/testKeychainStoreRoundTrip
196+
CLOUDFLARED_KEYCHAIN_TESTS=1 swift test --filter TokenStoreTests/testKeychainStoreRoundTrip
197197
```
198198

199199
## Docs
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
public enum SSHAccessHeader {
1+
public enum AccessHeader {
22
public static let accessToken = "Cf-Access-Token"
33
public static let clientID = "Cf-Access-Client-Id"
44
public static let clientSecret = "Cf-Access-Client-Secret"
@@ -8,6 +8,6 @@ public enum SSHAccessHeader {
88
public static let appAUD = "CF-Access-Aud"
99
}
1010

11-
public enum SSHAccessPath {
11+
public enum AccessPath {
1212
public static let login = "/cdn-cgi/access/login"
1313
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Foundation
22

3-
public struct SSHAppInfo: Sendable, Equatable {
3+
public struct AppInfo: Sendable, Equatable {
44
public let authDomain: String
55
public let appAUD: String
66
public let appDomain: String
@@ -12,55 +12,55 @@ public struct SSHAppInfo: Sendable, Equatable {
1212
}
1313
}
1414

15-
public enum SSHAppInfoParser {
16-
public static func parse(requestURL: URL, response: HTTPURLResponse) throws -> SSHAppInfo {
15+
public enum AppInfoParser {
16+
public static func parse(requestURL: URL, response: HTTPURLResponse) throws -> AppInfo {
1717
guard let finalURL = response.url, let authDomain = finalURL.host, !authDomain.isEmpty else {
18-
throw SSHFailure.protocolViolation("response is missing final URL host")
18+
throw Failure.protocolViolation("response is missing final URL host")
1919
}
2020

21-
let appDomain = response.value(forHTTPHeaderField: SSHAccessHeader.appDomain) ?? ""
21+
let appDomain = response.value(forHTTPHeaderField: AccessHeader.appDomain) ?? ""
2222
guard !appDomain.isEmpty else {
23-
throw SSHFailure.protocolViolation("missing \(SSHAccessHeader.appDomain) header")
23+
throw Failure.protocolViolation("missing \(AccessHeader.appDomain) header")
2424
}
2525

2626
let appAUD: String
27-
if finalURL.path.contains(SSHAccessPath.login) {
27+
if finalURL.path.contains(AccessPath.login) {
2828
appAUD = URLComponents(url: finalURL, resolvingAgainstBaseURL: false)?
2929
.queryItems?
3030
.first(where: { $0.name == "kid" })?
3131
.value ?? ""
3232
guard !appAUD.isEmpty else {
33-
throw SSHFailure.protocolViolation("missing kid query parameter in login redirect")
33+
throw Failure.protocolViolation("missing kid query parameter in login redirect")
3434
}
35-
} else if let headerAUD = response.value(forHTTPHeaderField: SSHAccessHeader.appAUD), !headerAUD.isEmpty {
35+
} else if let headerAUD = response.value(forHTTPHeaderField: AccessHeader.appAUD), !headerAUD.isEmpty {
3636
appAUD = headerAUD
3737
} else {
38-
throw SSHFailure.protocolViolation("unable to resolve app AUD for \(requestURL.absoluteString)")
38+
throw Failure.protocolViolation("unable to resolve app AUD for \(requestURL.absoluteString)")
3939
}
4040

41-
return SSHAppInfo(authDomain: authDomain, appAUD: appAUD, appDomain: appDomain)
41+
return AppInfo(authDomain: authDomain, appAUD: appAUD, appDomain: appDomain)
4242
}
4343
}
4444

45-
public protocol SSHHTTPClient: Sendable {
45+
public protocol HTTPClient: Sendable {
4646
func send(_ request: URLRequest) async throws -> (Data, HTTPURLResponse)
4747
}
4848

49-
public struct SSHAppInfoResolver: Sendable {
50-
private let client: any SSHHTTPClient
49+
public struct AppInfoResolver: Sendable {
50+
private let client: any HTTPClient
5151
private let userAgent: String
5252

53-
public init(client: any SSHHTTPClient, userAgent: String = "swift-cloudflared") {
53+
public init(client: any HTTPClient, userAgent: String = "swift-cloudflared") {
5454
self.client = client
5555
self.userAgent = userAgent
5656
}
5757

58-
public func resolve(appURL: URL) async throws -> SSHAppInfo {
58+
public func resolve(appURL: URL) async throws -> AppInfo {
5959
var request = URLRequest(url: appURL)
6060
request.httpMethod = "HEAD"
6161
request.setValue(userAgent, forHTTPHeaderField: "User-Agent")
6262

6363
let (_, response) = try await client.send(request)
64-
return try SSHAppInfoParser.parse(requestURL: appURL, response: response)
64+
return try AppInfoParser.parse(requestURL: appURL, response: response)
6565
}
6666
}

0 commit comments

Comments
 (0)