瀏覽代碼

Added Forgot Password Feature

master
30117125 4 年之前
父節點
當前提交
efe2c77256

+ 53
- 0
UnivateProperties_API/Controllers/Users/RegisterController.cs 查看文件

100
             }
100
             }
101
         }
101
         }
102
 
102
 
103
+        //Writes to DB
104
+        [AllowAnonymous]
105
+        [HttpPost("forgotPassword/{mail}")]
106
+        public IActionResult ForgotPassword(string mail)
107
+        {
108
+            try
109
+            {
110
+                _Repo.ForgotPasswordMailCheck(mail);
111
+                return Ok();
112
+            }
113
+            catch(Exception ex)
114
+            {
115
+                return new BadRequestResult();
116
+            }
117
+        }
118
+
103
         //Writes to DB
119
         //Writes to DB
104
         [AllowAnonymous]
120
         [AllowAnonymous]
105
         [HttpPost("registeragency")]
121
         [HttpPost("registeragency")]
120
                 return BadRequest(new { message = ex.Message });
136
                 return BadRequest(new { message = ex.Message });
121
             }
137
             }
122
         }
138
         }
139
+
140
+        public class FPTOKEN
141
+        {
142
+            public string token { get; set; }
143
+        }
144
+
145
+        [AllowAnonymous]
146
+        [HttpPost("fptoken")]
147
+        public IActionResult GetIndiv([FromBody] FPTOKEN fpToken)
148
+        {
149
+            try
150
+            {
151
+                var indiv = _Repo.GetIndividualByFPToken(fpToken.token);
152
+                return new OkObjectResult(indiv);
153
+            }
154
+            catch (Exception ex)
155
+            {
156
+                return new NoContentResult();
157
+            }
158
+        }
159
+
160
+        [AllowAnonymous]
161
+        [HttpPut("passwordUpdate")]
162
+        public IActionResult UpdateUserPassword([FromBody]UserDto userParam)
163
+        {
164
+            if (userParam != null)
165
+            {
166
+                _Repo.UpdatePassword(userParam);
167
+                return Ok();
168
+            }
169
+            else
170
+            {
171
+                return new NoContentResult();
172
+            }
173
+            
174
+            
175
+        }
123
     }
176
     }
124
 }
177
 }

+ 61
- 0
UnivateProperties_API/Helpers/ClsCrypto.cs 查看文件

1
+using System;
2
+using System.Security.Cryptography;
3
+using System.Text;
4
+
5
+namespace UnivateProperties_API.Helpers
6
+{
7
+    public class ClsCrypto
8
+    {
9
+        private RijndaelManaged myRijndael = new RijndaelManaged();
10
+        private int iterations;
11
+        private byte[] salt;
12
+
13
+        public ClsCrypto(string strPassword)
14
+        {
15
+            myRijndael.BlockSize = 128;
16
+            myRijndael.KeySize = 128;
17
+            myRijndael.IV = HexStringToByteArray("e84ad660c4721ae0e84ad660c4721ae0");
18
+
19
+            myRijndael.Padding = PaddingMode.PKCS7;
20
+            myRijndael.Mode = CipherMode.CBC;
21
+            iterations = 1000;
22
+            salt = Encoding.UTF8.GetBytes("insight123resultxyz");
23
+            myRijndael.Key = GenerateKey(strPassword);
24
+        }
25
+
26
+        public string Encrypt(string strPlainText)
27
+        {
28
+            byte[] strText = new System.Text.UTF8Encoding().GetBytes(strPlainText);
29
+            ICryptoTransform transform = myRijndael.CreateEncryptor();
30
+            byte[] cipherText = transform.TransformFinalBlock(strText, 0, strText.Length);
31
+
32
+            return Convert.ToBase64String(cipherText);
33
+        }
34
+
35
+        public string Decrypt(string encryptedText)
36
+        {
37
+            byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
38
+            var decryptor = myRijndael.CreateDecryptor(myRijndael.Key, myRijndael.IV);
39
+            byte[] originalBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
40
+
41
+            return Encoding.UTF8.GetString(originalBytes);
42
+        }
43
+
44
+        public static byte[] HexStringToByteArray(string strHex)
45
+        {
46
+            dynamic r = new byte[strHex.Length / 2];
47
+            for (int i = 0; i <= strHex.Length - 1; i += 2)
48
+            {
49
+                r[i / 2] = Convert.ToByte(Convert.ToInt32(strHex.Substring(i, 2), 16));
50
+            }
51
+            return r;
52
+        }
53
+
54
+        private byte[] GenerateKey(string strPassword)
55
+        {
56
+            Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(System.Text.Encoding.UTF8.GetBytes(strPassword), salt, iterations);
57
+
58
+            return rfc2898.GetBytes(128 / 8);
59
+        }
60
+    }
61
+}

+ 1662
- 0
UnivateProperties_API/Migrations/20201022063435_UserFPToken.Designer.cs
文件差異過大導致無法顯示
查看文件


+ 22
- 0
UnivateProperties_API/Migrations/20201022063435_UserFPToken.cs 查看文件

1
+using Microsoft.EntityFrameworkCore.Migrations;
2
+
3
+namespace UnivateProperties_API.Migrations
4
+{
5
+    public partial class UserFPToken : Migration
6
+    {
7
+        protected override void Up(MigrationBuilder migrationBuilder)
8
+        {
9
+            migrationBuilder.AddColumn<string>(
10
+                name: "FPToken",
11
+                table: "Users",
12
+                nullable: true);
13
+        }
14
+
15
+        protected override void Down(MigrationBuilder migrationBuilder)
16
+        {
17
+            migrationBuilder.DropColumn(
18
+                name: "FPToken",
19
+                table: "Users");
20
+        }
21
+    }
22
+}

+ 2
- 0
UnivateProperties_API/Migrations/DataContextModelSnapshot.cs 查看文件

1332
 
1332
 
1333
                     b.Property<DateTime>("Created");
1333
                     b.Property<DateTime>("Created");
1334
 
1334
 
1335
+                    b.Property<string>("FPToken");
1336
+
1335
                     b.Property<bool>("IsDeleted");
1337
                     b.Property<bool>("IsDeleted");
1336
 
1338
 
1337
                     b.Property<bool>("LoginPasswordChange");
1339
                     b.Property<bool>("LoginPasswordChange");

+ 1
- 0
UnivateProperties_API/Model/Users/User.cs 查看文件

33
         public string Token { get; set; }
33
         public string Token { get; set; }
34
         public bool AcceptedTerms { get; set; }
34
         public bool AcceptedTerms { get; set; }
35
         public bool LoginPasswordChange { get; set; }
35
         public bool LoginPasswordChange { get; set; }
36
+        public string FPToken { get; set; }
36
         #endregion Properties
37
         #endregion Properties
37
 
38
 
38
         #region Methods
39
         #region Methods

+ 38
- 0
UnivateProperties_API/Repository/Communication/MailRepository.cs 查看文件

23
             _dbContext = db;
23
             _dbContext = db;
24
         }
24
         }
25
 
25
 
26
+        public MailRepository()
27
+        {
28
+        }
29
+
26
         MimeMessage messageObj = new MimeMessage();
30
         MimeMessage messageObj = new MimeMessage();
27
         MailboxAddress from;
31
         MailboxAddress from;
28
         MailboxAddress to;
32
         MailboxAddress to;
109
             client.Disconnect(true);
113
             client.Disconnect(true);
110
             client.Dispose();
114
             client.Dispose();
111
         }
115
         }
116
+
117
+        public void ForgotPassword(MailModel mm, string link)
118
+        {
119
+            string name = mm.Name;
120
+            string email = mm.Email;
121
+
122
+            from = new MailboxAddress("Admin", mm.FromAddress);
123
+
124
+            to = new MailboxAddress("User", mm.ToAddress);
125
+
126
+            messageObj.From.Add(from);
127
+            messageObj.To.Add(to);
128
+
129
+            messageObj.Subject = "Uni-Vate - Password Reset Request";
130
+
131
+            bodyBuilder.HtmlBody = "<div style=\"margin: 5px\">" +
132
+                "<h4>Request to reset password</h4>" +
133
+                "<h4>Dear " + name + " there has been a request  to reset your password. If this is incorrect please send an email to info@univateproperties.co.za</h4>" +
134
+                "<div>" +
135
+                "<h3>"+ link + "</h3>" +
136
+
137
+                "</div>" +
138
+                "</div>" +
139
+                "</div>";
140
+
141
+            messageObj.Body = bodyBuilder.ToMessageBody();
142
+
143
+            client.Connect("smtp.gmail.com", 465, true);
144
+            client.Authenticate("jlouw365@gmail.com", "setskohatxpsceqo");
145
+
146
+            client.Send(messageObj);
147
+            client.Disconnect(true);
148
+            client.Dispose();
149
+        }
112
     }
150
     }
113
 }
151
 }

+ 3
- 0
UnivateProperties_API/Repository/Users/IRegisterRepository.cs 查看文件

12
         Agency CreateAgency(AgencyDto agency);
12
         Agency CreateAgency(AgencyDto agency);
13
         void CreatePerson(UserDto individual, PersonType personType, bool save, Agency agency);
13
         void CreatePerson(UserDto individual, PersonType personType, bool save, Agency agency);
14
         void Update(User userParam, string password = null);
14
         void Update(User userParam, string password = null);
15
+        Individual GetIndividualByFPToken(string fpToken);
15
         IEnumerable<User> GetAllUsers();
16
         IEnumerable<User> GetAllUsers();
16
         IEnumerable<Agency> GetAllAgencies();
17
         IEnumerable<Agency> GetAllAgencies();
17
         IEnumerable<Individual> GetAllIndividuals();
18
         IEnumerable<Individual> GetAllIndividuals();
22
         void DeleteAgency(int id);
23
         void DeleteAgency(int id);
23
         void DeleteIndividual(int id);
24
         void DeleteIndividual(int id);
24
         SimplePersonDto UserDetails(int userId);
25
         SimplePersonDto UserDetails(int userId);
26
+        void ForgotPasswordMailCheck(string mail);
27
+        void UpdatePassword(UserDto user);
25
     }
28
     }
26
 }
29
 }

+ 89
- 0
UnivateProperties_API/Repository/Users/RegisterRepository.cs 查看文件

1
 using Microsoft.AspNetCore.Authorization;
1
 using Microsoft.AspNetCore.Authorization;
2
+using Microsoft.AspNetCore.Mvc;
3
+using System;
2
 using System.Collections.Generic;
4
 using System.Collections.Generic;
5
+using System.Drawing.Text;
3
 using System.Linq;
6
 using System.Linq;
7
+using System.Text;
4
 using UnivateProperties_API.Containers.Users;
8
 using UnivateProperties_API.Containers.Users;
5
 using UnivateProperties_API.Containers.Users.Simple;
9
 using UnivateProperties_API.Containers.Users.Simple;
6
 using UnivateProperties_API.Context;
10
 using UnivateProperties_API.Context;
258
             }
262
             }
259
         }
263
         }
260
 
264
 
265
+        public void UpdatePassword(UserDto userParam)
266
+        {
267
+            var indiv = _dbContext.Individuals.Where(x => x.Email == userParam.Email).FirstOrDefault();
268
+            var user = _dbContext.Users.Where(x => x.Id == indiv.UserId).FirstOrDefault();
269
+
270
+            MyCommon.CreatePasswordHash(userParam.Password, out byte[] passwordHash, out byte[] passwordSalt);
271
+
272
+            user.PasswordHash = passwordHash;
273
+            user.PasswordSalt = passwordSalt;
274
+            user.FPToken = "";
275
+
276
+            _dbContext.Users.Update(user);
277
+            Save();
278
+        }
279
+
261
         private void Save()
280
         private void Save()
262
         {
281
         {
263
             _dbContext.SaveChanges();
282
             _dbContext.SaveChanges();
338
                 };
357
                 };
339
             }
358
             }
340
         }
359
         }
360
+
361
+        public Individual GetIndividualByFPToken(string fpToken)
362
+        {
363
+            string linkStr = fpToken.Replace('!', '/');
364
+            var user = _dbContext.Users.Where(usr => usr.FPToken == linkStr).FirstOrDefault();
365
+
366
+            if (user != null)
367
+            {
368
+                var indiv = _dbContext.Individuals.Where(x => x.UserId == user.Id).FirstOrDefault();
369
+                return indiv;
370
+            }
371
+            else
372
+            {
373
+                throw new Exception();
374
+            }            
375
+        }
376
+
377
+        public void ForgotPasswordMailCheck(string mail)
378
+        {
379
+            var indiv = _dbContext.Individuals.Where(x => x.Email.ToUpper() == mail.ToUpper()).FirstOrDefault();
380
+            var mailer = new MailRepository();
381
+            if (indiv != null)
382
+            {
383
+                byte[] time = BitConverter.GetBytes(GetTime());
384
+                byte[] mailByte = Encoding.ASCII.GetBytes(mail);
385
+                var timeStr = GetTime().ToString();
386
+                byte[] timeArr = Encoding.ASCII.GetBytes(timeStr);
387
+                byte[] key = Guid.NewGuid().ToByteArray();
388
+
389
+                string token = Convert.ToBase64String((timeArr.Concat(key).ToArray()).Concat(mailByte).ToArray());
390
+
391
+                string secureKey = "EGV~A8pn;:9&zC]6";
392
+
393
+                //encrypt token
394
+
395
+                ClsCrypto lockey = new ClsCrypto(secureKey);
396
+
397
+                var encryptedToken = lockey.Encrypt(token);
398
+                var individual = _dbContext.Individuals.Where(e => e.Email == mail).FirstOrDefault();
399
+                var user = _dbContext.Users.Where(x => x.Id == individual.UserId).FirstOrDefault();
400
+
401
+                //send ecrypted token to db
402
+                user.FPToken = encryptedToken;
403
+
404
+                _dbContext.Users.Update(user);
405
+                _dbContext.SaveChanges();
406
+
407
+                string linkStr = encryptedToken.Replace('/', '!');
408
+
409
+                //change below to test locally or QA
410
+                //string url = "http://localhost:8080/#/forgotPasswordReset/" + linkStr;
411
+                string url = "http://training.provision-sa.com:122/#/forgotPasswordReset/" + linkStr;
412
+
413
+                mailer.ForgotPassword(new MailModel
414
+                {
415
+                    ToAddress = mail,
416
+                    FromAddress = "jlouw365@gmail.com",
417
+                    Name = indiv.Name
418
+                }, url);
419
+            }
420
+            else
421
+            {
422
+                throw new Exception();
423
+            }
424
+        }
425
+
426
+        private double GetTime()
427
+        {
428
+            return DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
429
+        }
341
     }
430
     }
342
 }
431
 }

Loading…
取消
儲存