Skip to content

Commit

Permalink
Added proper Base64 URL coding support
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitribouniol committed Dec 6, 2024
1 parent a547dbb commit c617669
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
33 changes: 33 additions & 0 deletions Sources/WebPush/Helpers/DataProtocol+Base64URLCoding.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// DataProtocol+Base64URLCoding.swift
// swift-webpush
//
// Created by Dimitri Bouniol on 2024-12-06.
// Copyright © 2024 Mochi Development, Inc. All rights reserved.
//

import Foundation

extension DataProtocol {
func base64URLEncodedString() -> String {
Data(self)
.base64EncodedString()
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
}
}

extension DataProtocol where Self: RangeReplaceableCollection {
init?(base64URLEncoded string: String) {
var base64String = string.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
while base64String.count % 4 != 0 {
base64String = base64String.appending("=")
}

guard let decodedData = Data(base64Encoded: base64String)
else { return nil }

self = Self(decodedData)
}
}
2 changes: 1 addition & 1 deletion Sources/WebPush/VAPID/VAPIDKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ extension VAPID.Key: Identifiable {
}

public var id: ID {
ID(privateKey.publicKey.x963Representation.base64EncodedString()) // TODO: make url-safe
ID(privateKey.publicKey.x963Representation.base64URLEncodedString())
}
}
25 changes: 25 additions & 0 deletions Tests/WebPushTests/Base64URLCodingTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Base64URLCodingTests.swift
// swift-webpush
//
// Created by Dimitri Bouniol on 2024-12-06.
// Copyright © 2024 Mochi Development, Inc. All rights reserved.
//

import Foundation
import Testing
@testable import WebPush

@Test func base64URLDecoding() async throws {
let string = ">>> Hello, swift-webpush world??? 🎉"
let base64Encoded = "Pj4+IEhlbGxvLCBzd2lmdC13ZWJwdXNoIHdvcmxkPz8/IPCfjok="
let base64URLEncoded = "Pj4-IEhlbGxvLCBzd2lmdC13ZWJwdXNoIHdvcmxkPz8_IPCfjok"
#expect(String(decoding: Data(base64URLEncoded: base64Encoded)!, as: UTF8.self) == string)
#expect(String(decoding: Data(base64URLEncoded: base64URLEncoded)!, as: UTF8.self) == string)
}

@Test func base64URLEncoding() async throws {
let string = ">>> Hello, swift-webpush world??? 🎉"
let base64URLEncoded = "Pj4-IEhlbGxvLCBzd2lmdC13ZWJwdXNoIHdvcmxkPz8_IPCfjok"
#expect(Array(string.utf8).base64URLEncodedString() == base64URLEncoded)
}

0 comments on commit c617669

Please sign in to comment.