Skip to content

Commit 6bce305

Browse files
Added proper Base64 URL coding support
1 parent a547dbb commit 6bce305

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// DataProtocol+Base64URLCoding.swift
3+
// swift-webpush
4+
//
5+
// Created by Dimitri Bouniol on 2024-12-06.
6+
// Copyright © 2024 Mochi Development, Inc. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
extension DataProtocol {
12+
func base64URLEncodedString() -> String {
13+
Data(self)
14+
.base64EncodedString()
15+
.replacingOccurrences(of: "+", with: "-")
16+
.replacingOccurrences(of: "/", with: "_")
17+
.replacingOccurrences(of: "=", with: "")
18+
}
19+
}
20+
21+
extension DataProtocol where Self: RangeReplaceableCollection {
22+
init?(base64URLEncoded string: String) {
23+
var base64String = string.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
24+
while base64String.count % 4 != 0 {
25+
base64String = base64String.appending("=")
26+
}
27+
28+
guard let decodedData = Data(base64Encoded: base64String)
29+
else { return nil }
30+
31+
self = Self(decodedData)
32+
}
33+
}

Sources/WebPush/VAPID/VAPIDKey.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,6 @@ extension VAPID.Key: Identifiable {
6969
}
7070

7171
public var id: ID {
72-
ID(privateKey.publicKey.x963Representation.base64EncodedString()) // TODO: make url-safe
72+
ID(privateKey.publicKey.x963Representation.base64URLEncodedString())
7373
}
7474
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Base64URLCodingTests.swift
3+
// swift-webpush
4+
//
5+
// Created by Dimitri Bouniol on 2024-12-06.
6+
// Copyright © 2024 Mochi Development, Inc. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import Testing
11+
@testable import WebPush
12+
13+
@Test func base64URLDecoding() async throws {
14+
let string = ">>> Hello, swift-webpush world??? 🎉"
15+
let base64Encoded = "Pj4+IEhlbGxvLCBzd2lmdC13ZWJwdXNoIHdvcmxkPz8/IPCfjok="
16+
let base64URLEncoded = "Pj4-IEhlbGxvLCBzd2lmdC13ZWJwdXNoIHdvcmxkPz8_IPCfjok"
17+
#expect(String(decoding: Data(base64URLEncoded: base64Encoded)!, as: UTF8.self) == string)
18+
#expect(String(decoding: Data(base64URLEncoded: base64URLEncoded)!, as: UTF8.self) == string)
19+
}
20+
21+
@Test func base64URLEncoding() async throws {
22+
let string = ">>> Hello, swift-webpush world??? 🎉"
23+
let base64URLEncoded = "Pj4-IEhlbGxvLCBzd2lmdC13ZWJwdXNoIHdvcmxkPz8_IPCfjok"
24+
#expect(Array(string.utf8).base64URLEncodedString() == base64URLEncoded)
25+
}

0 commit comments

Comments
 (0)