New updates
This commit is contained in:
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env swift
|
||||
import Foundation
|
||||
import CryptoKit
|
||||
|
||||
struct Payload: Codable {
|
||||
let licenseID: String
|
||||
let customerName: String?
|
||||
let customerEmail: String?
|
||||
let edition: String
|
||||
let installationID: String
|
||||
let issuedAt: Date
|
||||
let expiresAt: Date?
|
||||
let maxMajorVersion: Int?
|
||||
}
|
||||
|
||||
func base64URL(_ data: Data) -> String {
|
||||
data.base64EncodedString()
|
||||
.replacingOccurrences(of: "+", with: "-")
|
||||
.replacingOccurrences(of: "/", with: "_")
|
||||
.replacingOccurrences(of: "=", with: "")
|
||||
}
|
||||
|
||||
let args = CommandLine.arguments
|
||||
func value(_ flag: String) -> String? {
|
||||
guard let index = args.firstIndex(of: flag), index + 1 < args.count else { return nil }
|
||||
return args[index + 1]
|
||||
}
|
||||
|
||||
guard let installationID = value("--installation-id"), UUID(uuidString: installationID) != nil else {
|
||||
fputs("Usage: swift Scripts/license-sign.swift --installation-id UUID [--name NAME] [--email EMAIL] [--edition Professional] [--license-id ID] [--max-major 1] [--expires YYYY-MM-DD]\n", stderr)
|
||||
exit(2)
|
||||
}
|
||||
|
||||
let fm = FileManager.default
|
||||
let defaultPrivate = fm.homeDirectoryForCurrentUser.appendingPathComponent("Library/Application Support/Rsync Studio Licensing/license-private-key.txt")
|
||||
let privateURL = value("--private-key").map { URL(fileURLWithPath: $0) } ?? defaultPrivate
|
||||
let privateText = try String(contentsOf: privateURL, encoding: .utf8).trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard let privateData = Data(base64Encoded: privateText) else { throw NSError(domain: "RsyncStudioLicensing", code: 1, userInfo: [NSLocalizedDescriptionKey: "Private key is not Base64."]) }
|
||||
let privateKey = try Curve25519.Signing.PrivateKey(rawRepresentation: privateData)
|
||||
|
||||
var expiry: Date?
|
||||
if let text = value("--expires") {
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
formatter.dateFormat = "yyyy-MM-dd"
|
||||
formatter.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
guard let date = formatter.date(from: text) else {
|
||||
fputs("Invalid --expires date; use YYYY-MM-DD.\n", stderr)
|
||||
exit(2)
|
||||
}
|
||||
expiry = date
|
||||
}
|
||||
|
||||
let payload = Payload(
|
||||
licenseID: value("--license-id") ?? UUID().uuidString.lowercased(),
|
||||
customerName: value("--name"),
|
||||
customerEmail: value("--email"),
|
||||
edition: value("--edition") ?? "Professional",
|
||||
installationID: installationID.lowercased(),
|
||||
issuedAt: Date(),
|
||||
expiresAt: expiry,
|
||||
maxMajorVersion: value("--max-major").flatMap(Int.init) ?? 1
|
||||
)
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.outputFormatting = [.sortedKeys]
|
||||
encoder.dateEncodingStrategy = .iso8601
|
||||
let data = try encoder.encode(payload)
|
||||
let signature = try privateKey.signature(for: data)
|
||||
let token = "RS3.\(base64URL(data)).\(base64URL(signature))"
|
||||
print(token)
|
||||
Reference in New Issue
Block a user