From d7781c5532a9aa1d684694b019352428d00e5816 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 16 Mar 2022 09:12:42 -0500 Subject: [PATCH] updated Signed-off-by: Matt Bruce --- JSONCreator_iOS/JSONCreator/AppDelegate.swift | 25 ++- .../Samples/AccountSecurityValidation.json | 195 ++++++++++++++++++ .../JSON/Samples/DigitFieldValidation.json | 133 ++++++++++++ .../JSON/Samples/FormEnabledChain.json | 2 +- .../JSON/Samples/MultipleErrorMsgExample.json | 142 +++++++++++++ .../WebViewBridgeTrialFraudUserGet.swift | 136 ++++++------ .../WebViewBridgeTrialFraudUserGetModel.swift | 70 +++---- 7 files changed, 590 insertions(+), 113 deletions(-) create mode 100644 JSONCreator_iOS/JSONCreator/JSON/Samples/AccountSecurityValidation.json create mode 100644 JSONCreator_iOS/JSONCreator/JSON/Samples/DigitFieldValidation.json create mode 100644 JSONCreator_iOS/JSONCreator/JSON/Samples/MultipleErrorMsgExample.json diff --git a/JSONCreator_iOS/JSONCreator/AppDelegate.swift b/JSONCreator_iOS/JSONCreator/AppDelegate.swift index ce55d94..31dab66 100644 --- a/JSONCreator_iOS/JSONCreator/AppDelegate.swift +++ b/JSONCreator_iOS/JSONCreator/AppDelegate.swift @@ -7,7 +7,7 @@ // import UIKit -import MVMCoreUI +import CoreTelephony extension Decodable { static func map(JSONString:String) -> Self? { @@ -68,12 +68,28 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele } } self.register() - - let json = ["actionType" : "trialFraudDeviceCheckGet"] + //getCT() + let json = ["actionType" : WebViewBridgeTrialFraudUserGetModel.identifier] self.testBridge(json: json) return true } +// func getCT() { +// let info: CTTelephonyNetworkInfo = CTTelephonyNetworkInfo() +// if #available(iOS 12.0, *) { +// for (service, carrier) in info.serviceSubscriberCellularProviders ?? [:] { +// print("\(service), \(carrier)") +// print(carrier.carrierName!) +// print(carrier.mobileCountryCode!) +// print(carrier.mobileNetworkCode!) +// print(carrier.isoCountryCode!) +// print(carrier.allowsVOIP) +// } +// } else { +// // Fallback on earlier versions +// } +// } + @objc func jsonPasteAndGo(_ sender: UILongPressGestureRecognizer) { if sender.state == .ended { (dvc as? DetailViewController)?.textView.text = UIPasteboard.general.string @@ -152,7 +168,7 @@ extension AppDelegate { func register(){ ModelRegistry.register(handler: WebViewBridgeTrialFraudDeviceCheckGet.self, for: WebViewBridgeTrialFraudDeviceCheckGetModel.self) //ModelRegistry.register(handler: WebViewBridgeTrialFraudUserSet.self, for: WebViewBridgeTrialFraudUserSetModel.self) - //ModelRegistry.register(handler: WebViewBridgeTrialFraudUserGet.self, for: WebViewBridgeTrialFraudUserGetModel.self) + ModelRegistry.register(handler: WebViewBridgeTrialFraudUserGet.self, for: WebViewBridgeTrialFraudUserGetModel.self) ModelRegistry.register(handler: EmailVerifyField.self, for: EmailVerifyModel.self) ModelRegistry.register(handler: PillLabel.self, for: PillLabelModel.self) ModelRegistry.register(handler: SampleWebViewBridge.self, for: SampleWebViewBridgeModel.self) @@ -172,7 +188,6 @@ extension AppDelegate { print("Thread isMain: \(Thread.isMainThread)") anyHandler.perform(then: { result in print("Thread isMain: \(Thread.isMainThread)") - let value = try? result.get() switch result{ case .success(let value): if let value = value { diff --git a/JSONCreator_iOS/JSONCreator/JSON/Samples/AccountSecurityValidation.json b/JSONCreator_iOS/JSONCreator/JSON/Samples/AccountSecurityValidation.json new file mode 100644 index 0000000..1eea56d --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/JSON/Samples/AccountSecurityValidation.json @@ -0,0 +1,195 @@ +{ + "ResponseInfo": { + "locale": "EN", + "server": "10-74-170-83.ebiz.verizon.com-mf_prepayss01", + "code": "00000", + "hideNotificationLogo": false, + "message": "0", + "buildNumber": "6698", + "type": "Success", + "requestId": "dbb1ee17-69fe-464e-8a82-9563b83422ab", + "topAlertTime": 0 + }, + "Page": { + "navigationBar": { + "moleculeName": "navigationBar", + "title": "Account security" + }, + "pageType": "tbd", + "cache": false, + "screenHeading": "Account security", + "template": "stack", + "header": { + "moleculeName": "header", + "molecule": { + "moleculeName": "headlineBody", + "headline": { + "moleculeName": "label", + "text": "Next up, let's secure this account." + }, + "body": { + "moleculeName": "label", + "attributes": [ + { + "topPadding": 30, + "length": 19, + "action": { + "actionType": "openPage", + "analyticsData": { + "vzdl.page.pageLinkName": "/mf/Manage Profile|Email Verify", + "vzdl.page.linkName": "Verify" + }, + "pageType": "whyWeAskingAEMPR" + }, + "location": 113, + "type": "action" + } + ], + "text": "We'll use this PIN and security question for verification and help accessing the account. Make sure the PIN meets these requirements." + } + } + }, + "stack": { + "moleculeName": "stack", + "molecules": [ + { + "moleculeName": "stackItem", + "horizontalAlignment": "leading", + "molecule": { + "moleculeName": "digitTextField", + "editable": true, + "title": "Account security PIN", + "digits": 4, + "fieldKey": "securityPIN" + } + }, + { + "moleculeName": "stackItem", + "horizontalAlignment": "leading", + "molecule": { + "moleculeName": "digitTextField", + "editable": true, + "title": "Confirm account security PIN", + "type": "secure", + "digits": 4, + "fieldKey": "confirmSecurityPIN" + } + }, + { + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "dropDown", + "fieldKey": "securityQuestion", + "title": "Security question", + "options": [ + "What was the first live concert you attended?", + "Where did you and your spouse first meet?", + "What was your favorite place to visit as a child?", + "What was the first name of your first roommate?", + "What is the name of a memorable place?", + "What is the first name of your best friend?", + "What was your favorite restaurant in college?" + ], + "selectedIndex": 0 + } + }, + { + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "textField", + "title": "Security answer", + "type": "text", + "fieldKey": "securityAnswer" + } + }, + { + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "label", + "text": "Be sure to remember these details. They'll be needed to access the account later." + } + } + ] + }, + "footer": { + "moleculeName": "footer", + "molecule": { + "moleculeName": "twoButtonView", + "primaryButton": { + "groupName": "default", + "moleculeName": "button", + "title": "Next", + "action": { + "analyticsData": { + "vzdl.page.linkName": "Legal Disclosure" + }, + "fieldKey": "next", + "actionType": "openPage", + "extraParameters": { + "from": "none" + }, + "presentationStyle": "push", + "pageType": "legalDisclosurePR" + } + } + } + }, + "formRules": [ + { + "groupName": "default", + "rules": [ + { + "regex": "^(?!.*0123|.*1234|.*2345|.*3456|.*4567|.*5678|.*6789|.*3210|.*4321|.*5432|.*6543|.*7654|.*8765|.*9876|.*0000|.*1111|.*2222|.*3333|.*4444|.*5555|.*6666|.*7777|.*8888|.*9999).*$", + "type": "regex", + "fields": [ + "securityPIN" + ], + "errorMessage": { + "securityPIN": "Your PIN can't have numbers in order or repeating." + } + }, + { + "type": "equals", + "fields": [ + "securityPIN", + "confirmSecurityPIN" + ], + "errorMessage": { + "confirmSecurityPIN": "Your account PIN entries don't match. Try again." + } + }, + { + "type": "regex", + "regex": "^[A-Za-z0-9 ]{3,10}$", + "fields": [ + "securityAnswer" + ], + "errorMessage": { + "securityAnswer": "Your security answer can only letters, numbers, spaces, and periods." + } + }, + { + "type": "regex", + "regex": "^.{3,10}$", + "fields": [ + "securityAnswer" + ], + "errorMessage": { + "securityAnswer": "Your answer must be between 3-10 characters." + } + }, + { + "type": "allRequired", + "ruleId": "requiredRule", + "fields": [ + "securityPIN", + "confirmSecurityPIN", + "securityAnswer" + ] + } + ] + } + ] + } + } + diff --git a/JSONCreator_iOS/JSONCreator/JSON/Samples/DigitFieldValidation.json b/JSONCreator_iOS/JSONCreator/JSON/Samples/DigitFieldValidation.json new file mode 100644 index 0000000..180c4d2 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/JSON/Samples/DigitFieldValidation.json @@ -0,0 +1,133 @@ +{ + "ResponseInfo": { + "locale": "EN", + "server": "10-74-170-83.ebiz.verizon.com-mf_prepayss01", + "code": "00000", + "hideNotificationLogo": false, + "message": "0", + "buildNumber": "6698", + "type": "Success", + "requestId": "dbb1ee17-69fe-464e-8a82-9563b83422ab", + "topAlertTime": 0 + }, + "Page": { + "navigationBar": { + "moleculeName": "navigationBar", + "title": "Account security" + }, + "pageType": "tbd", + "cache": false, + "screenHeading": "Account security", + "template": "stack", + "stack": { + "moleculeName": "stack", + "molecules": [ + { + "moleculeName": "stackItem", + "horizontalAlignment": "leading", + "molecule": { + "moleculeName": "digitTextField", + "editable": true, + "title": "Account security PIN", + "digits": 4, + "fieldKey": "securityPIN" + } + }, + { + "moleculeName": "stackItem", + "horizontalAlignment": "leading", + "molecule": { + "moleculeName": "digitTextField", + "editable": true, + "title": "Confirm account security PIN", + "type": "text", + "digits": 4, + "fieldKey": "confirmSecurityPIN" + } + }, + { + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "textField", + "fieldKey": "preferredFirstName", + "type": "text", + "text": "", + "errorMessage": "Please enter a valid first name.", + "title": "Preferred First Name", + "feedback": "This will replace greeting name if you have one.", + "required": false + } + } + ] + }, + "footer": { + "moleculeName": "footer", + "molecule": { + "moleculeName": "twoButtonView", + "primaryButton": { + "groupName": "default", + "moleculeName": "button", + "title": "Next", + "action": { + "analyticsData": { + "vzdl.page.linkName": "Legal Disclosure" + }, + "fieldKey": "next", + "actionType": "openPage", + "extraParameters": { + "from": "none" + }, + "presentationStyle": "push", + "pageType": "legalDisclosurePR" + } + } + } + }, + "formRules": [ + { + "groupName": "default", + "rules": [ + { + "regex": "^[0-6]{0,4}$", + "type": "regex", + "fields": [ + "securityPIN" + ], + "errorMessage": { + "securityPIN": "Your PIN can't have numbers in order or repeating." + } + }, + { + "type": "equals", + "fields": [ + "securityPIN", + "confirmSecurityPIN" + ], + "errorMessage": { + "confirmSecurityPIN": "Your account PIN entries don't match. Try again." + } + }, + { + "regex": "^[0-9a-zA-Z@\\.\\-\\’_?]{0,25}$", + "ruleId": "anyAlphaNumeric", + "errorMessage": { + "preferredFirstName": "Only use for First Name" + }, + "type": "regex", + "fields": [ + "preferredFirstName" + ] + }, + { + "type": "allRequired", + "ruleId": "requiredRule", + "fields": [ + "securityPIN", + "confirmSecurityPIN" + ] + } + ] + } + ] + } + } diff --git a/JSONCreator_iOS/JSONCreator/JSON/Samples/FormEnabledChain.json b/JSONCreator_iOS/JSONCreator/JSON/Samples/FormEnabledChain.json index e6aaef2..51dad23 100644 --- a/JSONCreator_iOS/JSONCreator/JSON/Samples/FormEnabledChain.json +++ b/JSONCreator_iOS/JSONCreator/JSON/Samples/FormEnabledChain.json @@ -162,7 +162,7 @@ ] }, { - "type": "equals", + "type": "equalsIgnoreCase", "ruleId": "passwordsEqual", "fields": [ "password", diff --git a/JSONCreator_iOS/JSONCreator/JSON/Samples/MultipleErrorMsgExample.json b/JSONCreator_iOS/JSONCreator/JSON/Samples/MultipleErrorMsgExample.json new file mode 100644 index 0000000..5734cc1 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/JSON/Samples/MultipleErrorMsgExample.json @@ -0,0 +1,142 @@ +{ + "ResponseInfo": { + "locale": "EN", + "server": "10-74-165-96.ebiz.verizon.com-mf_prepayss01", + "userMessage": "0", + "code": "00000", + "hideNotificationLogo": false, + "message": "0", + "buildNumber": "124", + "type": "Success", + "requestId": "2094e7b7-0325-4ca5-93a0-6462b99eb4fa", + "topAlertTime": 0 + }, + "Page": { + "analyticsData": { + "vzdl.page.flow": "account", + "vzwi.mvmapp.pageType": "planDetailsAEMPR", + "vzdl.page.subFlow": "plan details", + "vzdl.page.name": "/mf/account/prepaid plans/explore plans/plan details" + }, + "footer": { + "moleculeName": "footer", + "molecule": { + "moleculeName": "twoButtonView", + "primaryButton": { + "moleculeName": "button", + "action": { + "appContext": "mfPrepaySS", + "analyticsData": { + "vzdl.page.linkName": "Next" + }, + "actionType": "openPage", + "presentationStyle": "push", + "pageType": "tbd" + }, + "title": "Next", + "groupName": "default" + } + } + }, + "stack": { + "moleculeName": "stack", + "molecules": [ + { + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "label", + "text": "First name" + } + }, + { + "spacing": 0, + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "textField", + "fieldKey": "Firstname", + "text": "", + "type": "text" + } + }, + { + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "label", + "text": "Last name" + } + }, + { + "spacing": 0, + "moleculeName": "stackItem", + "molecule": { + "moleculeName": "textField", + "fieldKey": "Lastname", + "text": "", + "type": "text" + } + } + ] + }, + "formRules": [ + { + "groupName": "default", + "rules": [ + { + "regex": "^[a-zA-Z0-9._ ]{0,10}$", + "type": "regex", + "fields": [ + "Firstname", + "Lastname" + ], + "errorMessage": { + "Firstname": "Your first name can only letters, numbers, spaces, and periods.", + "Lastname": "Your last name can only letters, numbers, spaces, and periods." + } + }, + { + "fields": [ + "Firstname", + "Lastname" + ], + "type": "regex", + "regex": "^.{3,10}$", + "errorMessage": { + "Firstname":"Your first name must be between 3-10 characters.", + "Lastname": "Your last name must be between 3-10 characters." + } + }, + { + "type": "allRequired", + "ruleId": "requiredRule", + "fields": [ + "Firstname", + "Lastname" + ] + } + ] + } + ], + "pageType": "tbd", + "cache": false, + "screenHeading": "New device Profile", + "header": { + "moleculeName": "header", + "molecule": { + "moleculeName": "headlineBody", + "headline": { + "moleculeName": "label", + "text": "Who will be using this device?" + }, + "body": { + "moleculeName": "label", + "text": "We'll use these details to set up this account." + } + } + }, + "template": "stack", + "navigationBar": { + "moleculeName": "navigationBar", + "title": "New device Profile" + } + } +} diff --git a/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGet.swift b/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGet.swift index 31629ba..1d13332 100644 --- a/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGet.swift +++ b/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGet.swift @@ -1,75 +1,67 @@ -//// -//// WebviewBridgeTrialFraudUserGet.swift -//// MobileFirstFramework -//// -//// Created by Matt Bruce on 2/1/22. -//// Copyright © 2022 Verizon Wireless. All rights reserved. -//// // -//import Foundation -//import MVMCore +// WebviewBridgeTrialFraudUserGet.swift +// MobileFirstFramework // -//extension WebViewBridgeError { -// static var userCheckICloudNotAvailable = Self.other(code: 150, message: "usercheck_icloud_not_available") -// static var userCheckUserDecode = Self.other(code: 151, message: "usercheck_data_decode") -// static var userCheckUserEncode = Self.other(code: 152, message: "usercheck_data_encode") -// static var userCheckUserSynchronization = Self.other(code: 153, message: "usercheck_data_synchronize") -//} +// Created by Matt Bruce on 2/1/22. +// Copyright © 2022 Verizon Wireless. All rights reserved. // -//final class WebViewBridgeTrialFraudUserGet: WebViewBridgeHandlerProtocol { -// -// typealias Model = WebViewBridgeTrialFraudUserGetModel -// typealias ViewController = CoreViewControllerable -// -// //properties -// public var bridgeModel: Model! -// public var completionHandler: (([String : Any]?) -> Void)! -// public weak var viewController: ViewController? -// -// func runBridgeAction() { -// -// //current user state, default is iCloud not available -// //therefore if bridgeModel.isICloudAvaiable() == false -// //then this state is sent back in the "sendSuccess" and -// //this method will NEVER do a "sendError" unless the baseClass throws one -// var state: TrialFraudUserState = .notAvail -// -// //return dictionary -// var result: JSONDictionary = [:] -// -// //ensure that iCloud is available for current user -// if bridgeModel.isICloudAvaiable() { -// -// //keyValueStore hooked up to the user's iCloud account -// let keyValStore = NSUbiquitousKeyValueStore() -// -// //see if there is an existing object set for this user's iCloud account -// if let fraudUserData = keyValStore.data(forKey: TrialFraudUser.key) { -// -// //decode the data into a object -// guard let fraudUser: TrialFraudUser = try? fraudUserData.decode() else { -// sendError(for: .userCheckUserDecode) -// return -// } -// -// //current user state is "Set" since there is an existing value -// //and the user does have iCloud available -// state = .set -// //get the saved identifier out of the object within iCloud -// result["userIdentifier"] = fraudUser.identifier -// -// } else { -// -// //current user state is "Not Set" since there is NOT an existing value -// //and the user does have iCloud available -// state = .notSet -// } -// } -// -// //set the state string value -// result["state"] = state.rawValue -// -// //execute the completionHandler on the main thread -// sendSuccess(for: result) -// } -//} + +import Foundation +import MVMCore + +extension WebViewBridgeError { + static var userCheckICloudNotAvailable = Self.other(code: 150, message: "usercheck_icloud_not_available") + static var userCheckUserDecode = Self.other(code: 151, message: "usercheck_data_decode") + static var userCheckUserEncode = Self.other(code: 152, message: "usercheck_data_encode") + static var userCheckUserSynchronization = Self.other(code: 153, message: "usercheck_data_synchronize") +} + +final class WebViewBridgeTrialFraudUserGet: WebViewBridgeHandler { + + override func perform() { + + //current user state, default is iCloud not available + //therefore if bridgeModel.isICloudAvaiable() == false + //then this state is sent back in the "sendSuccess" and + //this method will NEVER do a "sendError" unless the baseClass throws one + var state: TrialFraudUserState = .notAvail + + //return dictionary + var result: JSONDictionary = [:] + + //ensure that iCloud is available for current user + if model.isICloudAvaiable() { + + //keyValueStore hooked up to the user's iCloud account + let keyValStore = NSUbiquitousKeyValueStore() + + //see if there is an existing object set for this user's iCloud account + if let fraudUserData = keyValStore.data(forKey: TrialFraudUser.key) { + + //decode the data into a object + guard let fraudUser: TrialFraudUser = try? fraudUserData.decode() else { + sendError(for: .userCheckUserDecode) + return + } + + //current user state is "Set" since there is an existing value + //and the user does have iCloud available + state = .set + //get the saved identifier out of the object within iCloud + result["userIdentifier"] = fraudUser.identifier + + } else { + + //current user state is "Not Set" since there is NOT an existing value + //and the user does have iCloud available + state = .notSet + } + } + + //set the state string value + result["state"] = state.rawValue + + //execute the completionHandler on the main thread + sendSuccess(for: result) + } +} diff --git a/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGetModel.swift b/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGetModel.swift index ff4195f..c721c34 100644 --- a/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGetModel.swift +++ b/JSONCreator_iOS/JSONCreator/NativeBridge/Trial/WebViewBridgeTrialFraudUserGetModel.swift @@ -1,38 +1,38 @@ -//// -//// WebviewBridgeTrialFraudUserGetModel.swift -//// MobileFirstFramework -//// -//// Created by Matt Bruce on 2/1/22. -//// Copyright © 2022 Verizon Wireless. All rights reserved. -//// // -//import Foundation +// WebviewBridgeTrialFraudUserGetModel.swift +// MobileFirstFramework // -//struct TrialFraudUser: Codable { -// static var key: String { return "trialFraudUser" } -// let identifier: String -// let date: Date -//} +// Created by Matt Bruce on 2/1/22. +// Copyright © 2022 Verizon Wireless. All rights reserved. // -//enum TrialFraudUserState: String, Encodable { -// case notAvail = "Not Available" -// case notSet = "Not Set" -// case set = "Set" -//} -// -//protocol TrialFraudUserModelProtocol {} -// -//extension TrialFraudUserModelProtocol { -// func isICloudAvaiable() -> Bool { -// guard let _ = FileManager.default.ubiquityIdentityToken else { -// return false -// } -// return true -// } -//} -// -//class WebViewBridgeTrialFraudUserGetModel: WebviewBridgeModelProtocol, TrialFraudUserModelProtocol { -// -// static var identifier: String = "trialFraudUserCheckGet" -// var jsCallback: String? -//} + +import Foundation + +struct TrialFraudUser: Codable { + static var key: String { return "trialFraudUser" } + let identifier: String + let date: Date +} + +enum TrialFraudUserState: String, Encodable { + case notAvail = "Not Available" + case notSet = "Not Set" + case set = "Set" +} + +protocol TrialFraudUserModelProtocol {} + +extension TrialFraudUserModelProtocol { + func isICloudAvaiable() -> Bool { + guard let _ = FileManager.default.ubiquityIdentityToken else { + return false + } + return true + } +} + +class WebViewBridgeTrialFraudUserGetModel: WebviewBridgeModelProtocol, TrialFraudUserModelProtocol { + + static var identifier: String = "trialFraudUserCheckGet" + var jsCallback: String? +}