-
-
Notifications
You must be signed in to change notification settings - Fork 139
/
Copy pathHelpers.swift
60 lines (48 loc) · 1.39 KB
/
Helpers.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import Foundation
import HTTPTypes
import IssueReporting
let base64UrlRegex = try! NSRegularExpression(
pattern: "^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)", options: .caseInsensitive)
/// Checks that the value somewhat looks like a JWT, does not do any additional parsing or verification.
func isJWT(_ value: String) -> Bool {
var token = value
if token.hasPrefix("Bearer ") {
token = String(token.dropFirst("Bearer ".count))
}
token = token.trimmingCharacters(in: .whitespacesAndNewlines)
guard !token.isEmpty else {
return false
}
let parts = token.split(separator: ".")
guard parts.count == 3 else {
return false
}
for part in parts {
if part.count < 4 || !isBase64Url(String(part)) {
return false
}
}
return true
}
func isBase64Url(_ value: String) -> Bool {
let range = NSRange(location: 0, length: value.utf16.count)
return base64UrlRegex.firstMatch(in: value, options: [], range: range) != nil
}
func checkAuthorizationHeader(
_ headers: HTTPFields,
fileID: StaticString = #fileID,
filePath: StaticString = #filePath,
line: UInt = #line,
column: UInt = #column
) {
guard let authorization = headers[.authorization] else { return }
if !isJWT(authorization) {
reportIssue(
"Authorization header does not contain a JWT",
fileID: fileID,
filePath: filePath,
line: line,
column: column
)
}
}