123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //
- // CryptoSettingViewModel.swift
- // Bark
- //
- // Created by huangfeng on 2022/11/10.
- // Copyright © 2022 Fin. All rights reserved.
- //
- import CryptoSwift
- import Foundation
- import RxCocoa
- import RxSwift
- class CryptoSettingViewModel: ViewModel, ViewModelType {
- struct Input {
- let algorithmChanged: Driver<String>
- let copyScript: Driver<CryptoSettingFields>
- let done: Driver<CryptoSettingFields>
- }
- struct Output {
- let initial: Driver<(algorithmList: [Algorithm], modeList: [String], paddingList: [String], initialFields: CryptoSettingFields?)>
- let modeListChanged: Driver<[String]>
- let paddingListChanged: Driver<[String]>
- let keyLengthChanged: Driver<Int>
- let showSnackbar: Driver<String>
- let done: Driver<Void>
- let copy: Driver<String>
- }
- struct Dependencies {
- let settingFieldRelay: BehaviorRelay<CryptoSettingFields?>
- let deviceKey: Driver<String>
- let serverAddress: Driver<String>
- }
- private let dependencies: Dependencies
- init(dependencies: Dependencies =
- Dependencies(
- settingFieldRelay: CryptoSettingRelay.shared.fields,
- // Key 好像没有对应的事件流,先“just”,懒得写了
- deviceKey: Driver.just(ServerManager.shared.currentServer.key),
- serverAddress: Driver.just(ServerManager.shared.currentServer.address)
- )
- ) {
- self.dependencies = dependencies
- }
- func transform(input: Input) -> Output {
- let showSnackbar = PublishRelay<String>()
- let modeList = input
- .algorithmChanged
- .compactMap { Algorithm(rawValue: $0) }
- .map { $0.modes }
- let keyLength =
- Driver.merge([
- Driver.just(dependencies.settingFieldRelay.value)
- .compactMap { $0 }
- .compactMap { Algorithm(rawValue: $0.algorithm)?.keyLength },
- input
- .algorithmChanged
- .compactMap { Algorithm(rawValue: $0)?.keyLength },
- ])
- // 保存配置
- let done = input.done
- .filter { fields in
- do {
- _ = try AESCryptoModel(cryptoFields: fields)
- return true
- }
- catch {
- showSnackbar.accept(error.rawString())
- return false
- }
- }
- done.drive(onNext: { [weak self] fields in
- // 保存设置
- self?.dependencies.settingFieldRelay.accept(fields)
- }).disposed(by: rx.disposeBag)
- let copyScript = input.copyScript
- .filter { [weak self] fields in
- do {
- _ = try AESCryptoModel(cryptoFields: fields)
- // 保存配置
- self?.dependencies.settingFieldRelay.accept(fields)
- return true
- }
- catch {
- showSnackbar.accept(error.rawString())
- return false
- }
- }
- let copy = Driver.combineLatest(copyScript, dependencies.deviceKey, dependencies.serverAddress)
- .map { fields, deviceKey,serverAddress in
- let key = fields.key ?? ""
- let iv = fields.iv ?? ""
- return
- """
- #!/usr/bin/env bash
-
- # Documentation: \(NSLocalizedString("encryptionUrl"))
-
- set -e
- # bark key
- deviceKey='\(deviceKey)'
- # push payload
- json='{"body": "test", "sound": "birdsong"}'
- # \(String(format: NSLocalizedString("keyComment"), Int(fields.algorithm.suffix(3))! / 8))
- key='\(key)'
- # \(NSLocalizedString("ivComment"))
- iv='\(iv)'
- # \(NSLocalizedString("opensslEncodingComment"))
- key=$(printf $key | xxd -ps -c 200)
- iv=$(printf $iv | xxd -ps -c 200)
-
- # \(NSLocalizedString("base64Notice"))
- ciphertext=$(echo -n $json | openssl enc -aes-\(fields.algorithm.suffix(3))-\(fields.mode.lowercased()) -K $key \(iv.count > 0 ? "-iv $iv " : "")| base64)
- # \(NSLocalizedString("consoleComment")) "\((try? AESCryptoModel(cryptoFields: fields).encrypt(text: "{\"body\": \"test\", \"sound\": \"birdsong\"}")) ?? "")"
- echo $ciphertext
-
- # \(NSLocalizedString("ciphertextComment"))
- curl --data-urlencode "ciphertext=$ciphertext"\( iv.count == 0 ? "" : " --data-urlencode \"iv=\(iv)\"") \(serverAddress)/$deviceKey
- """
- }
- return Output(
- initial: Driver.just((
- algorithmList: [Algorithm.aes128, Algorithm.aes192, Algorithm.aes256],
- modeList: ["CBC", "ECB", /* "GCM" */], // GCM 还没准备好示例代码,暂时禁用
- paddingList: ["pkcs7"],
- initialFields: dependencies.settingFieldRelay.value
- )),
- modeListChanged: modeList,
- paddingListChanged: Driver.just(["pkcs7"]),
- keyLengthChanged: keyLength,
- showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty()),
- done: done.map { _ in () },
- copy: copy
- )
- }
- }
|