Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
//
2
//  LoginView.swift
3
//  twogetskills
4
//
5
//  Created by Efrain Yanez Recanatini on 1/27/22.
6
//
7
 
8
import SwiftUI
9
import Network
10
import Alamofire
11
import SwiftyJSON
12
import SafariServices
13
import RNCryptor
14
 
15
 
16
struct LoginView: View {
17
 
18
    @Environment(\.openURL) var openURL
19
 
20
    private let colorTitle = UIColor(hex: Config.COLOR_TEXT_VIEW_TITLE);
21
 
22
    private let colorEditText = UIColor(hex: Config.COLOR_EDIT_TEXT);
23
 
24
    private let colorButtonIntroBackground = UIColor(hex: Config.COLOR_BUTTON_INTRO_BACKGROUND);
25
 
26
    private let colorButtonIntroForeground = UIColor(hex: Config.COLOR_BUTTON_INTRO_FOREGROUND);
27
 
28
 
29
 
30
 
31
    @State private var email: String = "efrain.yanez@leaderslinked.com"
32
 
33
    @State private var password: String = "Cesa2020$"
34
    @State private var goToMain : Bool = false
35
 
36
    @State private var showProgressView : Bool = false
37
 
38
    @State private var showInputError : Bool = false;
39
 
40
 
41
    @State private var errorMessageEmail : String = ""
42
 
43
    @State private var errorMessagePassword : String = ""
44
 
45
 
46
    @State private var presentAlert : Bool = false
47
    @State private var titleAlert : String = ""
48
    @State private var messageAlert : String = ""
49
 
50
 
51
    var body: some View {
52
 
53
 
54
 
55
        GeometryReader { geometry in
56
            ZStack {
57
 
58
 
59
                NavigationLink(
60
                    destination: MainView(),
61
                    isActive: self.$goToMain,
62
                    label: {
63
                        Text("")
64
                    })
65
 
66
 
67
                VStack {
68
 
69
                    Image(uiImage: UIImage(named: "logo") ?? UIImage())
70
                        .resizable()
71
                        .aspectRatio(contentMode: .fit)
72
                        .frame(width: geometry.size.width * 0.5)
73
                        .padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
74
                        /*
75
                                            .background(Color.white)
76
                                            .cornerRadius(8.0)
77
                                            .shadow(radius: 4.0)
78
                        */
79
 
80
                    Text("¿Ya tienes una cuenta? Registrarse")
81
                         .font(.headline)
82
                         .foregroundColor(Color(colorTitle ?? .red))
83
                        .padding(.top, 10)
84
 
85
                    TextField("Email", text: self.$email)
86
                            .frame(height: 35)
87
                            .textFieldStyle(PlainTextFieldStyle())
88
                            .padding([.horizontal], 4)
89
                            .background(Color(colorEditText ?? .red))
90
                            .cornerRadius(16)
91
                            .overlay(RoundedRectangle(cornerRadius: 16).stroke(Color.gray))
92
                            .padding([.horizontal], 24)
93
                            .font(.system(size: 14.0))
94
 
95
                    //if !self.errorMessageEmail.isEmpty {
96
 
97
                        Text(self.errorMessageEmail)
98
                            .foregroundColor(.red)
99
                            .font(.system(size: 12.0))
100
                            .padding(.top, 5)
101
                    //}
102
 
103
 
104
                    Group {
105
                        SecureField("Contraseña", text: self.$password)
106
                            .frame(height: 35)
107
                            .textFieldStyle(PlainTextFieldStyle())
108
                            .padding([.horizontal], 4)
109
                            .background(Color(colorEditText ?? .red))
110
                            .cornerRadius(16)
111
                            .overlay(RoundedRectangle(cornerRadius: 16).stroke(Color.gray))
112
                            .padding([.horizontal], 24)
113
                            .font(.system(size: 14.0))
114
                        }.padding(.top, 5)
115
 
116
                    //if !self.errorMessageEmail.isEmpty {
117
 
118
                        Text(self.errorMessagePassword)
119
         // }
120
                            .foregroundColor(.red)
121
                                  .font(.system(size: 12.0))
122
                                  .padding(.top, 5)
123
                                  .padding([.horizontal], 4)
124
 
125
 
126
                    Button(action: {
127
                        if(validate()) {
128
                            signin()
129
                        }
130
                    }, label: {
131
                        Text("ENTRAR")
132
                            .frame(width: 200)
133
                            .padding(.vertical, 12.0)
134
                            .foregroundColor(Color(colorButtonIntroForeground ?? .white))
135
                            .background(Color(colorButtonIntroBackground ?? .systemBlue))
136
                            .cornerRadius(10)
137
                     }).padding(.top, 20)
138
 
139
                    Button(action: {
140
                        openURL(URL(string: "https://leaderslinked.com/signup")!)
141
 
142
                    }, label: {
143
                        Text("CREAR CUENTA")
144
                            .frame(width: 200)
145
                            .padding(.vertical, 12.0)
146
                            .foregroundColor(Color(colorButtonIntroForeground ?? .white))
147
                            .background(Color(colorButtonIntroBackground ?? .systemBlue))
148
                            .cornerRadius(10)
149
                     }).padding(.top, 10)
150
 
151
                    Spacer()
152
                }.frame(width: geometry.size.width, height: geometry.size.height, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
153
 
154
                if(self.showProgressView) {
155
 
156
                    ProgressView()
157
                    .scaleEffect(3, anchor: .center)
158
                    .zIndex(1000)
159
                }
160
 
161
                Spacer()
162
 
163
            }
164
            .alert(isPresented: $presentAlert) {
165
                Alert(
166
                    title: Text(self.titleAlert),
167
                    message: Text(self.messageAlert),
168
                    dismissButton: .default(Text("Ok"))
169
                )
170
            }
171
            .navigationBarHidden(true)
172
            //.navigationBarBackButtonHidden(true)
173
            .frame(width: geometry.size.width, height: geometry.size.height, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
174
 
175
        }
176
    }
177
 
178
    private func signin() -> Void
179
    {
180
        let preference = Preference.sharedInstance
181
        let device_uuid = preference.deviceUuid
182
 
183
        print("signin")
184
        print(" aes  = \(preference.aes) " )
185
        print(" email  = \(self.email) " )
186
        print(" password  = \(self.password) " )
187
 
188
 
189
        let syncDao = SyncDao()
190
        if preference.aes.isEmpty  {
191
 
192
            let syncRecord = syncDao.selectOneByType(type: Constants.SYNC_ADAPTER_TYPE_DEVICE)
193
 
194
            if syncRecord.id > 0 {
195
                let syncAdapter = SyncAdapter()
196
                syncAdapter.sync {
197
                    success in
198
                }
199
            }
200
 
201
            self.titleAlert = "Dispositivo no registrado"
202
            self.messageAlert = "Espere un momento y vuelva a intentarlo"
203
            self.presentAlert = true
204
 
205
            return
206
        }
207
 
208
        self.showProgressView = true;
209
 
210
        let emailData = email.data(using: .utf8)!
211
        let emailCipherData = RNCryptor.encrypt(data: emailData, withPassword: preference.aes)
212
        let emailEncrypted = emailCipherData.base64EncodedString()
213
 
214
        let passwordData = password.data(using: .utf8)!
215
        let passwordCipherData = RNCryptor.encrypt(data: passwordData, withPassword: preference.aes)
216
        let passwordEncrypted = passwordCipherData.base64EncodedString()
217
 
218
 
219
        print(" email encrypted = \(emailEncrypted) " )
220
        print(" password encrypted = \(passwordEncrypted) " )
221
 
222
        let parameters = [
223
            Constants.POST_SIGNIN_FIELD_APPLICATION_ID: "\(Constants.GLOBAL_APPLICATION_ID)",
224
            Constants.POST_SYNC_FIELD_DEVICE_UUID: device_uuid,
225
            Constants.POST_SIGNIN_FIELD_EMAIL: emailEncrypted,
226
            Constants.POST_SIGNIN_FIELD_PASSWORD: passwordEncrypted,
227
            Constants.POST_SIGNIN_FIELD_ENCRYPTER: Constants.GLOBAL_ENCRYPTER
228
        ]
229
 
230
        let headers: HTTPHeaders = [
231
            .accept(Constants.HTTP_HEADER_ACCEPT)
232
        ]
233
 
234
        print("URL signin : \(Config.URL_SIGNIN)")
235
 
236
        self.showProgressView = true
237
        AF.request(Config.URL_SIGNIN, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{(response) in
238
            self.showProgressView = false
239
 
240
            switch response.result {
241
                case .success:
242
                    let json = try? JSON(data: response.data!)
243
 
244
                    print("json : \(json)")
245
 
246
                    if json?["success"] ?? "" != false {
247
                        let dataService = DataService()
248
 
249
                        if dataService.syncFromServer(json : json) {
250
 
251
                            let now = Date()
252
                            let dateFormatter = DateFormatter()
253
                            dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
254
                            let dateOn = dateFormatter.string(from: now)
255
 
256
                            var userLog = UserLogModel()
257
                            userLog.userUuid = preference.userUuid
258
                            userLog.activity = Constants.USER_LOG_ACTIVITY_SIGNIN
259
                            userLog.addedOn = dateOn
260
 
261
                            let userLogDao = UserLogDao()
262
                            userLogDao.insert(record: userLog)
263
 
264
                            var sync = SyncModel()
265
 
266
                            var json = userLog.toJson()
267
                            json[Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME] = Constants.SYNC_ADAPTER_DATA_TYPE_USER_LOG
268
 
269
                            sync = SyncModel();
270
                            sync.type = Constants.SYNC_ADAPTER_TYPE_SYNC
271
                            if let theJSONData = try?  JSONSerialization.data(withJSONObject: json, options: .prettyPrinted),
272
                                let data = String(data: theJSONData, encoding: String.Encoding.ascii) {
273
                                    sync.data = data
274
                                }
275
 
276
                            syncDao.insert(record : sync);
277
 
278
 
279
 
280
                            self.goToMain = true
281
                        }
282
                    } else {
283
                        let message = json?["data"].string ?? ""
284
                        if !message.isEmpty {
285
                            self.titleAlert = "Error"
286
                            self.messageAlert = message
287
                            self.presentAlert = true
288
                        }
289
                    }
290
 
291
                   return
292
 
293
                case .failure :
294
                    self.titleAlert = "Servidor no encontrado"
295
                    self.messageAlert = "Ocurrio un error de comunicación"
296
                    self.presentAlert = true
297
 
298
                    return
299
            }
300
 
301
 
302
 
303
 
304
            /*
305
            switch response.result {
306
                case .success:
307
 
308
 
309
                    print("Response Data : \(response.data!) ")
310
 
311
                    let json = try? JSON(data: response.data!)
312
                    if json?["success"] ?? "" != false {
313
                        let dataService = DataService()
314
 
315
                        if dataService.syncFromServer(json : json) {
316
                            self.goToMain = true
317
                        }
318
                    } else {
319
                        let message = json?["data"].string ?? ""
320
                        if !message.isEmpty {
321
                            self.titleAlert = "Error"
322
                            self.messageAlert = message
323
                            self.presentAlert = true
324
                        }
325
                    }
326
 
327
 
328
                    return
329
 
330
                case .failure:
331
                    self.titleAlert = "Servidor no encontrado"
332
                    self.messageAlert = "Ocurrio un error de comunicación"
333
                    self.presentAlert = true
334
 
335
                    return
336
            }*/
337
        }
338
    }
339
 
340
 
341
    private func validate() -> Bool
342
    {
343
        self.errorMessageEmail = ""
344
        self.errorMessagePassword = ""
345
 
346
        print("validate - email : \(email)")
347
        print("validate - password : \(password)")
348
 
349
        var isOk = true
350
        if email.isEmpty {
351
            self.errorMessageEmail = "No puede estar en blanco"
352
            isOk = false
353
        }
354
 
355
        if !checkEmail(email: email) {
356
            self.errorMessageEmail = "Formato invalido"
357
            isOk = false
358
        }
359
 
360
        if password.isEmpty {
361
            self.errorMessagePassword =  "No puede estar en blanco"
362
            isOk = false
363
        }
364
 
365
        if(!checkPassword(password: password)) {
366
            self.errorMessagePassword = "Formato invalido"
367
            isOk = false
368
        }
369
 
370
 
371
        return isOk
372
    }
373
 
374
 
375
    private func checkEmail(email : String) -> Bool {
376
        let regex = #"^[a-zA-Z0-9_\-\.~]{2,}@[a-zA-Z0-9_\-\.~]{2,}\.[a-zA-Z]{2,}$"#
377
 
378
        let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
379
        return predicate.evaluate(with: email) ? true : false;
380
    }
381
 
382
    private func checkPassword(password : String) -> Bool {
383
        let regexOld = #"^(?=.*\d+)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{6,16}$"#
384
        let regexNew = #"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\#\?\!\@\$\^\%\*\-]).{6,16}$"#
385
 
386
        let predicateNew = NSPredicate(format: "SELF MATCHES %@", regexNew)
387
        let predicateOld = NSPredicate(format: "SELF MATCHES %@", regexOld)
388
        if(predicateOld.evaluate(with: password)) {
389
            return true
390
        } else  if(predicateNew.evaluate(with: password)) {
391
            return true
392
        } else {
393
            return false
394
        }
395
    }
396
 
397
 
398
}
399
 
400
 
401
 
402
struct LoginView_Previews: PreviewProvider {
403
    static var previews: some View {
404
        LoginView()
405
    }
406
}
407