SignUpSignIn.swift 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. //
  2. // SignUpSignIn.swift
  3. // NexilisLite
  4. //
  5. // Created by Akhmad Al Qindi Irsyam on 17/01/23.
  6. //
  7. import UIKit
  8. import NotificationBannerSwift
  9. import nuSDKService
  10. import FirebaseAuth
  11. public class SignUpSignIn: UIViewController {
  12. @IBOutlet weak var descSignUpSignIn: UILabel!
  13. @IBOutlet weak var usernameField: UITextField!
  14. @IBOutlet weak var passwordField: PasswordTextField!
  15. @IBOutlet weak var showPasswordButton: UIButton!
  16. @IBOutlet weak var descDisclaimer: UILabel!
  17. @IBOutlet weak var topConstDesc: NSLayoutConstraint!
  18. public var forceLogin = false
  19. public var isEmail = false
  20. public var isMSISDN = false
  21. public override func viewDidLoad() {
  22. super.viewDidLoad()
  23. // self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
  24. var textTitle = "Please enter your nickname and your password".localized()
  25. var subTitle = "Disclaimer : Signing up with a nickname provides full privacy since".localized() + " \(Bundle.main.infoDictionary?["CFBundleName"] as! String) " + "does not know your identity, which is usually linked to your email account or mobile number. However, if you use a nickname, we will not be able to reset your password if you lose or forget it, so please keep your password secure.".localized()
  26. var textPlaceHolder = "Your Nickname".localized()
  27. if isEmail {
  28. textTitle = "Please enter your registered email address.".localized()
  29. subTitle = ""
  30. textPlaceHolder = "Your Email".localized()
  31. } else if isMSISDN {
  32. textTitle = "Please enter your registered phone number.".localized()
  33. subTitle = ""
  34. textPlaceHolder = "Your Phone Number (082...)".localized()
  35. }
  36. descSignUpSignIn.text = textTitle
  37. descDisclaimer.text = subTitle
  38. descDisclaimer.font = UIFont.italicSystemFont(ofSize: 14)
  39. passwordField.addPadding(.right(40))
  40. passwordField.isSecureTextEntry = true
  41. showPasswordButton.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  42. usernameField.placeholder = textPlaceHolder
  43. passwordField.placeholder = "Password".localized()
  44. usernameField.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .mainColor
  45. passwordField.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .mainColor
  46. usernameField.addTarget(self, action: #selector(checkUsername(_:)), for: .editingChanged)
  47. showPasswordButton.addTarget(self, action: #selector(showPassword), for: .touchUpInside)
  48. let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
  49. tapGesture.cancelsTouchesInView = false
  50. view.addGestureRecognizer(tapGesture)
  51. if isEmail || isMSISDN {
  52. self.title = "Sign-In".localized()
  53. passwordField.isHidden = true
  54. showPasswordButton.isHidden = true
  55. if isMSISDN{
  56. usernameField.keyboardType = .numberPad
  57. }
  58. } else {
  59. self.title = "Sign-Up/Sign-In".localized()
  60. }
  61. let controllers = self.navigationController?.viewControllers
  62. if forceLogin && (controllers!.count < 2 || !(controllers![controllers!.count - 2] is SignInOption)) {
  63. navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(didTapCancel(sender:)))
  64. }
  65. self.navigationController?.navigationBar.topItem?.backButtonTitle = ""
  66. }
  67. public override func viewDidAppear(_ animated: Bool) {
  68. let attributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
  69. let navBarAppearance = UINavigationBarAppearance()
  70. navBarAppearance.configureWithOpaqueBackground()
  71. navBarAppearance.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : UIColor.mainColor
  72. navBarAppearance.titleTextAttributes = attributes
  73. navigationController?.navigationBar.standardAppearance = navBarAppearance
  74. navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
  75. navigationController?.navigationBar.tintColor = .white
  76. navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Submit".localized(), style: .plain, target: self, action: #selector(didTapSubmit(sender:)))
  77. }
  78. @objc func didTapCancel(sender: Any) {
  79. self.navigationController?.dismiss(animated: true)
  80. }
  81. @objc func checkUsername(_ textField: UITextField) {
  82. // let text : String! = usernameField.text
  83. // if isValidEmail(text) {
  84. // passwordField.isHidden = true
  85. // showPasswordButton.isHidden = true
  86. // } else if passwordField.isHidden {
  87. // passwordField.isHidden = false
  88. // showPasswordButton.isHidden = false
  89. // }
  90. }
  91. func isValidEmail(_ email: String) -> Bool {
  92. let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
  93. let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
  94. return emailPred.evaluate(with: email)
  95. }
  96. @objc func dismissKeyboard() {
  97. //Causes the view (or one of its embedded text fields) to resign the first responder status.
  98. view.endEditing(true)
  99. }
  100. @objc func showPassword() {
  101. if passwordField.isSecureTextEntry {
  102. passwordField.isSecureTextEntry = false
  103. showPasswordButton.setImage(UIImage(systemName: "eye.fill"), for: .normal)
  104. } else {
  105. passwordField.isSecureTextEntry = true
  106. showPasswordButton.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  107. }
  108. }
  109. func checkEmail(email: String) {
  110. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  111. self.showFailedSignUpIn(title: "Check your connection".localized(), withLoader: false)
  112. return
  113. }
  114. Nexilis.showLoader()
  115. DispatchQueue.global().async {
  116. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendOTPLogin(p_email: email), timeout: 30 * 1000) {
  117. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") != "00" {
  118. DispatchQueue.main.async {
  119. self.showFailedSignUpIn(title: "Unregistered email account".localized())
  120. }
  121. } else {
  122. DispatchQueue.main.async {
  123. Nexilis.hideLoader(completion: {
  124. self.showPageOTP(email: email)
  125. })
  126. }
  127. }
  128. } else {
  129. DispatchQueue.main.async {
  130. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  131. }
  132. }
  133. }
  134. }
  135. func checkNumber(number: String) {
  136. var number = number
  137. if number.hasPrefix("0") {
  138. number = number.replacingCharacters(in: number.startIndex...number.startIndex, with: "+62")
  139. }
  140. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  141. self.showFailedSignUpIn(title: "Check your connection".localized(), withLoader: false)
  142. return
  143. }
  144. self.sendOTP(to: number)
  145. }
  146. func sendOTP(to phoneNumber: String) {
  147. PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in
  148. if let error = error {
  149. UIApplication.shared.visibleViewController?.view.makeToast("Error sending OTP: \(error)".localized(), duration: 3, position: .center)
  150. return
  151. }
  152. Utils.setUserMSISDN(value: verificationID ?? "")
  153. self.showPageOTP(phone: phoneNumber)
  154. }
  155. }
  156. func verifyOTP(_ code: String, number: String, privateKey: SecKey) {
  157. let verificationID = Utils.getUserMSISDN()
  158. let credential = PhoneAuthProvider.provider().credential(
  159. withVerificationID: verificationID,
  160. verificationCode: code
  161. )
  162. Auth.auth().signIn(with: credential) { authResult, error in
  163. if error != nil {
  164. self.showFailedSignUpIn(title: "Invalid OTP".localized())
  165. self.showPageOTP(phone: number)
  166. return
  167. }
  168. DispatchQueue.global().async {
  169. if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChalanger()) {
  170. if response.isOk() {
  171. let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
  172. if data.isEmpty {
  173. DispatchQueue.main.async {
  174. self.showFailedSignUpIn(title: "Failed to get auth, please try again".localized())
  175. }
  176. return
  177. }
  178. var pk = ""
  179. var sign = ""
  180. let df = HMACDeviceFingerprintNexilis.generate()
  181. if let dataSign = "\(data)!\(df)".data(using: .utf8) {
  182. if let signature = KeyManagerNexilis.sign(data: dataSign, privateKey: privateKey) {
  183. sign = signature.base64EncodedString()
  184. }
  185. }
  186. if let publicKey = KeyManagerNexilis.getRSAX509PublicKeyBase64(privateKey: privateKey) {
  187. pk = publicKey
  188. }
  189. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendVerifyChangeDevice(p_email: "", p_vercode: "", number: number, deviceFingerprint: df, publicKey: pk, signature: sign), timeout: 30 * 1000) {
  190. if !response.isOk() {
  191. DispatchQueue.main.async {
  192. DispatchQueue.main.async {
  193. self.showFailedSignUpIn(title: "Failed".localized())
  194. }
  195. }
  196. } else {
  197. self.successSubmit(response: response, first: "", last: "", number: number)
  198. }
  199. } else {
  200. DispatchQueue.main.async {
  201. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  202. }
  203. }
  204. } else {
  205. DispatchQueue.main.async {
  206. self.showFailedSignUpIn(title: "Failed to get auth, please try again".localized())
  207. }
  208. }
  209. } else {
  210. DispatchQueue.main.async {
  211. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  212. }
  213. }
  214. }
  215. }
  216. }
  217. func showPageOTP(email: String = "", phone: String = "", errCode:String = "") {
  218. let showOTPVC = VerifyEmail()
  219. showOTPVC.email = email
  220. showOTPVC.msisdn = phone
  221. showOTPVC.isMSISDN = !phone.isEmpty
  222. showOTPVC.showWrongOTP = errCode
  223. showOTPVC.isDismiss = { code in
  224. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  225. self.showFailedSignUpIn(title: "Check your connection".localized(), withLoader: false)
  226. return
  227. }
  228. if KeyManagerNexilis.hasGeneratedKey() {
  229. KeyManagerNexilis.deleteKey()
  230. KeyManagerNexilis.deleteMarker()
  231. }
  232. KeyManagerNexilis.generateKey()
  233. KeyManagerNexilis.saveMarker()
  234. guard let privateKey = KeyManagerNexilis.getPrivateKey() else {
  235. KeyManagerNexilis.deleteKey()
  236. KeyManagerNexilis.deleteMarker()
  237. UIApplication.shared.visibleViewController?.view.makeToast("Biometric or passcode authentication required".localized(), duration: 3, position: .center)
  238. return
  239. }
  240. if Database.shared.openDatabase() == 0 {
  241. APIS.showRestartApp()
  242. KeyManagerNexilis.deleteKey()
  243. KeyManagerNexilis.deleteMarker()
  244. return
  245. }
  246. Nexilis.showLoader()
  247. if !phone.isEmpty {
  248. self.verifyOTP(code, number: phone, privateKey: privateKey)
  249. return
  250. }
  251. DispatchQueue.global().async {
  252. if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChalanger()) {
  253. if response.isOk() {
  254. let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
  255. if data.isEmpty {
  256. DispatchQueue.main.async {
  257. self.showFailedSignUpIn(title: "Failed to get auth, please try again".localized())
  258. }
  259. return
  260. }
  261. var pk = ""
  262. var sign = ""
  263. let df = HMACDeviceFingerprintNexilis.generate()
  264. if let dataSign = "\(data)!\(df)".data(using: .utf8) {
  265. if let signature = KeyManagerNexilis.sign(data: dataSign, privateKey: privateKey) {
  266. sign = signature.base64EncodedString()
  267. }
  268. }
  269. if let publicKey = KeyManagerNexilis.getRSAX509PublicKeyBase64(privateKey: privateKey) {
  270. pk = publicKey
  271. }
  272. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendVerifyChangeDevice(p_email: email, p_vercode: code, deviceFingerprint: df, publicKey: pk, signature: sign), timeout: 30 * 1000) {
  273. if !response.isOk() {
  274. DispatchQueue.main.async {
  275. Nexilis.hideLoader {
  276. self.showPageOTP(email: email, errCode: response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99"))
  277. }
  278. }
  279. } else {
  280. self.successSubmit(response: response, first: "", last: "", email: email)
  281. }
  282. } else {
  283. DispatchQueue.main.async {
  284. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  285. }
  286. }
  287. } else {
  288. DispatchQueue.main.async {
  289. self.showFailedSignUpIn(title: "Failed to get auth, please try again".localized())
  290. }
  291. }
  292. } else {
  293. DispatchQueue.main.async {
  294. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  295. }
  296. }
  297. }
  298. }
  299. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
  300. self.navigationController?.present(showOTPVC, animated: true, completion: nil)
  301. })
  302. }
  303. private func showFailedSignUpIn(title: String, withLoader: Bool = true) {
  304. KeyManagerNexilis.deleteKey()
  305. KeyManagerNexilis.deleteMarker()
  306. if withLoader {
  307. Nexilis.hideLoader(completion: {
  308. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  309. imageView.tintColor = .white
  310. let banner = FloatingNotificationBanner(title: title, subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  311. banner.show()
  312. })
  313. } else {
  314. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  315. imageView.tintColor = .white
  316. let banner = FloatingNotificationBanner(title: title, subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  317. banner.show()
  318. }
  319. }
  320. @objc func didTapSubmit(sender: Any) {
  321. guard let name = usernameField.text, !name.isEmpty else {
  322. var text = "Username"
  323. if isEmail {
  324. text = "Email"
  325. } else if isMSISDN {
  326. text = "Phone Number"
  327. }
  328. self.showFailedSignUpIn(title: "\(text) can't be empty".localized(), withLoader: false)
  329. return
  330. }
  331. if isEmail {
  332. if !isValidEmail(name) {
  333. self.showFailedSignUpIn(title: "Invalid email format. Please enter a valid email address".localized(), withLoader: false)
  334. } else {
  335. checkEmail(email: name)
  336. }
  337. return
  338. }
  339. if isMSISDN {
  340. checkNumber(number: name)
  341. return
  342. }
  343. let a = name.split(separator: " ", maxSplits: 1)
  344. let first = String(a[0])
  345. let last = a.count == 2 ? String(a[1]) : ""
  346. if first.count > 24 {
  347. self.showFailedSignUpIn(title: "First name is too long".localized(), withLoader: false)
  348. return
  349. }
  350. if last.count > 24 {
  351. self.showFailedSignUpIn(title: "Last name is too long".localized(), withLoader: false)
  352. return
  353. }
  354. let idMe = User.getMyPin()!
  355. if !name.matches("^[a-zA-Z0-9 ]*$") {
  356. self.showFailedSignUpIn(title: "Contains prohibited characters. Only alphabetic characters are allowed.".localized(), withLoader: false)
  357. return
  358. }
  359. let password = passwordField.text ?? ""
  360. if !passwordField.isHidden {
  361. if password.isEmpty {
  362. self.showFailedSignUpIn(title: "Password can't be empty".localized(), withLoader: false)
  363. return
  364. }
  365. if password.count < 6 {
  366. self.showFailedSignUpIn(title: "Password min 6 character".localized(), withLoader: false)
  367. return
  368. }
  369. }
  370. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  371. self.showFailedSignUpIn(title: "Check your connection".localized(), withLoader: false)
  372. return
  373. }
  374. if KeyManagerNexilis.hasGeneratedKey() {
  375. KeyManagerNexilis.deleteKey()
  376. KeyManagerNexilis.deleteMarker()
  377. }
  378. KeyManagerNexilis.generateKey()
  379. KeyManagerNexilis.saveMarker()
  380. guard let privateKey = KeyManagerNexilis.getPrivateKey() else {
  381. KeyManagerNexilis.deleteKey()
  382. KeyManagerNexilis.deleteMarker()
  383. UIApplication.shared.visibleViewController?.view.makeToast("Biometric or passcode authentication required".localized(), duration: 3, position: .center)
  384. return
  385. }
  386. if Database.shared.openDatabase() == 0 {
  387. APIS.showRestartApp()
  388. KeyManagerNexilis.deleteKey()
  389. KeyManagerNexilis.deleteMarker()
  390. return
  391. }
  392. Nexilis.showLoader()
  393. DispatchQueue.global().async {
  394. if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChalanger()) {
  395. if response.isOk() {
  396. let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
  397. if data.isEmpty {
  398. DispatchQueue.main.async {
  399. self.showFailedSignUpIn(title: "Failed to get auth, please try again".localized())
  400. }
  401. return
  402. }
  403. let md5Hex = password
  404. var pk = ""
  405. var sign = ""
  406. let df = HMACDeviceFingerprintNexilis.generate()
  407. if let dataSign = "\(data)!\(df)".data(using: .utf8) {
  408. if let signature = KeyManagerNexilis.sign(data: dataSign, privateKey: privateKey) {
  409. sign = signature.base64EncodedString()
  410. }
  411. }
  412. if let publicKey = KeyManagerNexilis.getRSAX509PublicKeyBase64(privateKey: privateKey) {
  413. pk = publicKey
  414. }
  415. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpSignInAPI(p_name: name, p_password: md5Hex, deviceFingerprint: df, publicKey: pk, signature: sign), timeout: 30 * 1000) {
  416. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  417. DispatchQueue.main.async {
  418. self.showFailedSignUpIn(title: "Invalid user / Username and password does not match".localized())
  419. }
  420. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  421. DispatchQueue.main.async {
  422. self.showFailedSignUpIn(title: "Failed, unknown user".localized())
  423. }
  424. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "4u" {
  425. DispatchQueue.main.async {
  426. self.showFailedSignUpIn(title: "Failed, blocked user".localized())
  427. }
  428. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "13" {
  429. DispatchQueue.main.async {
  430. self.showFailedSignUpIn(title: "Failed, This user is not registered on this device".localized())
  431. }
  432. } else if !response.isOk() {
  433. DispatchQueue.main.async {
  434. self.showFailedSignUpIn(title: "Failed".localized())
  435. }
  436. } else {
  437. self.successSubmit(response: response, first: first, last: last)
  438. }
  439. } else {
  440. DispatchQueue.main.async {
  441. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  442. }
  443. }
  444. } else {
  445. DispatchQueue.main.async {
  446. self.showFailedSignUpIn(title: "Failed to get auth, please try again".localized())
  447. }
  448. }
  449. } else {
  450. DispatchQueue.main.async {
  451. self.showFailedSignUpIn(title: "Unable to access servers. Try again later".localized())
  452. }
  453. }
  454. }
  455. }
  456. private func successSubmit(response: TMessage, first: String, last: String, email: String = "", number: String = "") {
  457. let sign = response.getBody(key: CoreMessage_TMessageKey.SIGN, default_value: "")
  458. if sign == "1" || !email.isEmpty || !number.isEmpty {
  459. let id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
  460. let f_pin = response.getBody(key: CoreMessage_TMessageKey.F_PIN_REAL, default_value: "")
  461. let device_id = response.getBody(key: CoreMessage_TMessageKey.IMEI, default_value: id)
  462. let last_sign = response.getBody(key: CoreMessage_TMessageKey.LAST_SIGN, default_value: "0")
  463. //print("last sign: \(last_sign)")
  464. if last_sign != "0" {
  465. Utils.setLoginMultipleFPin(value: f_pin)
  466. DispatchQueue.main.async {
  467. let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
  468. imageView.tintColor = .white
  469. let banner = FloatingNotificationBanner(title: "Multiple Login Detected...".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .info, colors: nil, iconPosition: .center)
  470. banner.show()
  471. }
  472. DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
  473. Nexilis.hideLoader(completion: {
  474. if Nexilis.showFB {
  475. Nexilis.floatingButton.removeFromSuperview()
  476. Nexilis.floatingButton = FloatingButton()
  477. Nexilis.addFB()
  478. }
  479. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onRefreshWebView"), object: nil, userInfo: nil)
  480. if self.forceLogin {
  481. self.navigationController?.dismiss(animated: true)
  482. } else {
  483. let controllers = self.navigationController?.viewControllers
  484. if controllers![controllers!.count - 2] is SignInOption {
  485. self.navigationController?.popToViewController(controllers![0], animated: true)
  486. } else {
  487. self.navigationController?.popViewController(animated: true)
  488. }
  489. }
  490. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
  491. let dialog = DialogUnableAccess()
  492. dialog.modalTransitionStyle = .crossDissolve
  493. dialog.modalPresentationStyle = .overCurrentContext
  494. UIApplication.shared.visibleViewController?.present(dialog, animated: true)
  495. })
  496. })
  497. })
  498. return
  499. }
  500. self.deleteAllRecordDatabase()
  501. if(!id.isEmpty) {
  502. // Nexilis.changeUser(f_pin: device_id)
  503. SecureUserDefaults.shared.set(device_id, forKey: "device_id")
  504. Utils.setProfile(value: true)
  505. // pos registration
  506. _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
  507. DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
  508. Nexilis.hideLoader(completion: {
  509. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  510. imageView.tintColor = .white
  511. let banner = FloatingNotificationBanner(title: "Successfully Sign-In".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  512. banner.show()
  513. if Nexilis.showFB {
  514. Nexilis.floatingButton.removeFromSuperview()
  515. Nexilis.floatingButton = FloatingButton()
  516. Nexilis.addFB()
  517. }
  518. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onRefreshWebView"), object: nil, userInfo: nil)
  519. if self.forceLogin {
  520. self.navigationController?.dismiss(animated: true)
  521. } else {
  522. let controllers = self.navigationController?.viewControllers
  523. if controllers![controllers!.count - 2] is SignInOption {
  524. self.navigationController?.popToViewController(controllers![controllers!.count - 3], animated: true)
  525. } else {
  526. self.navigationController?.popViewController(animated: true)
  527. }
  528. }
  529. })
  530. })
  531. }
  532. } else {
  533. let idMe = User.getMyPin()!
  534. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  535. var firstN = first
  536. if firstN.isEmpty {
  537. if !email.isEmpty {
  538. firstN = email
  539. } else {
  540. firstN = number
  541. }
  542. }
  543. do {
  544. if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT * FROM BUDDY where f_pin = '\(idMe)' ") {
  545. if !cursorData.next() {
  546. _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: idMe))
  547. } else {
  548. _ = Database.shared.updateRecord(fmdb: fmdb, table: "BUDDY", cvalues: ["first_name": first , "last_name": last], _where: "f_pin = '\(idMe)'")
  549. }
  550. cursorData.close()
  551. }
  552. } catch {
  553. rollback.pointee = true
  554. print("Access database error: \(error.localizedDescription)")
  555. }
  556. })
  557. Utils.setProfile(value: true)
  558. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onRefreshWebView"), object: nil, userInfo: nil)
  559. DispatchQueue.main.async {
  560. Nexilis.hideLoader(completion: {
  561. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  562. imageView.tintColor = .white
  563. let banner = FloatingNotificationBanner(title: "Successfully Sign-Up".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  564. banner.show()
  565. if self.forceLogin {
  566. self.navigationController?.dismiss(animated: true)
  567. } else {
  568. let controllers = self.navigationController?.viewControllers
  569. if controllers![controllers!.count - 2] is SignInOption {
  570. self.navigationController?.popToViewController(controllers![controllers!.count - 3], animated: true)
  571. } else {
  572. self.navigationController?.popViewController(animated: true)
  573. }
  574. }
  575. })
  576. }
  577. }
  578. }
  579. }