浏览代码

Create the login process.

Lee Morgan 11 月之前
父节点
当前提交
ac5a828e3c
共有 5 个文件被更改,包括 102 次插入32 次删除
  1. 7 7
      src/views/js/EncryptionHandler.js
  2. 17 0
      src/views/js/data/Account.js
  3. 1 10
      src/views/js/data/User.js
  4. 60 3
      src/views/js/pages/Login.js
  5. 17 12
      src/views/js/pages/Register.js

+ 7 - 7
src/views/js/EncryptionHandler.js

@@ -1,11 +1,11 @@
 export default class EncryptionHandler {
-    constructor(key, salt){
+    constructor(key){
         this._key = key;
     }
 
     static async create(password, salt){
-        const key = await this.generateEncryptionKey(password, salt);
-        return new EncryptionHandler(key, salt);
+        const key = await EncryptionHandler.generateEncryptionKey(password, salt);
+        return new EncryptionHandler(key);
     }
 
     static async hashPassword(password, salt){
@@ -53,7 +53,7 @@ export default class EncryptionHandler {
         return Uint8Array.from(atob(str), c => c.charCodeAt(0));
     }
 
-    async generateEncryptionKey(password, salt){
+    static async generateEncryptionKey(password, salt){
         const passwordKey = await crypto.subtle.importKey(
             "raw",
             new TextEncoder().encode(password),
@@ -65,7 +65,7 @@ export default class EncryptionHandler {
         return crypto.subtle.deriveKey(
             {
                 name: "PBKDF2",
-                salt: salt,
+                salt: Uint8Array.from(atob(salt), c => c.charCodeAt(0)),
                 iterations: 100000,
                 hash: "SHA-256"
             },
@@ -96,8 +96,8 @@ export default class EncryptionHandler {
     }
 
     async decrypt(data, key, ivString){
-        const encrypted = stringToBuffer(data);
-        const iv = stringToBuffer(ivString);
+        const encrypted = this.stringToBuffer(data);
+        const iv = this.stringToBuffer(ivString);
 
         const decrypted = await crypto.subtle.decrypt(
             {

+ 17 - 0
src/views/js/data/Account.js

@@ -0,0 +1,17 @@
+import EncryptionHandler from "../EncryptionHandler.js";
+
+export default class Account{
+    constructor(parent, id, data){
+        this._parent = parent;
+        this._id = id;
+        this._balance = data.balance;
+        this._income = data.income;
+        this._bills = data.bills;
+        this._allowances = data.allowances;
+        this._transactions = [];
+    }
+
+    static async decryptAndCreate(parent, id, data){
+        
+    }
+}

+ 1 - 10
src/views/js/data/User.js

@@ -1,11 +1,10 @@
 import EncryptionHandler from "../EncryptionHandler.js";
 
 export default class User{
-    constructor(id, name, email, salt, accounts = []){
+    constructor(id, name, email, accounts = []){
         this._id = id;
         this._name = name;
         this._email = email;
-        this._salt = salt;
         this._accounts = accounts;
     }
 
@@ -20,12 +19,4 @@ export default class User{
             encryption_salt: EncryptionHandler.generateSalt()
         };
     }
-
-    get id(){
-        return this._id;
-    }
-
-    get salt(){
-        return this._salt;
-    }
 }

+ 60 - 3
src/views/js/pages/Login.js

@@ -1,5 +1,8 @@
 import Page from "./Page.js";
 import Elem from "../Elem.js";
+import EncryptionHandler from "../EncryptionHandler.js";
+import User from "../data/User.js";
+import Notifier from "../Notifier.js";
 
 export default class Login extends Page{
     constructor(){
@@ -8,15 +11,66 @@ export default class Login extends Page{
         this.render();
     }
 
-    submit(){
+    async submit(){
         event.preventDefault();
-        console.log("submitting");
+
+        const email = this.container.querySelector(".email").value;
+        const password = this.container.querySelector(".password").value;
+
+        fetch("/api/user/salt", {
+            method: "POST",
+            headers: {
+                "Content-Type": "application/json"
+            },
+            body: JSON.stringify({email})
+        })
+            .then(r=>r.json())
+            .then((response)=>{
+                if(response.error) throw response;
+
+                let hashPromise = EncryptionHandler.hashPassword(password, response.password_salt);
+                return Promise.all([hashPromise, email, response.password_salt]);
+            })
+            .then((data)=>{
+                return fetch("/api/user/login", {
+                    method: "POST",
+                    headers: {"Content-Type": "application/json"},
+                    body: JSON.stringify({
+                        password_hash: data[0],
+                        email: data[1],
+                        password_salt: data[2]
+                    })
+                });
+            })
+            .then(r=>r.json())
+            .then((response)=>{
+                if(response.error) throw response;
+
+                window.user = new User(
+                    response.id,
+                    response.name,
+                    response.email,
+                    response.accounts
+                );
+                return EncryptionHandler.create(password, response.encryption_salt);
+            })
+            .then((encryptionHandler)=>{
+                window.encryptionHandler = encryptionHandler;
+                changePage("home");
+            })
+            .catch((err)=>{
+                if(err.error){
+                    new Notifier("error", err.error.message);
+                }else{
+                    new Notifier("error", "Something went wrong, try refreshing the page");
+                }
+            });
     }
 
     render(){
         new Elem("form")
             .addClass("standardForm")
-            .onsubmit(this.submit)
+            .onsubmit(this.submit.bind(this))
             .append(new Elem("h1")
                 .text("Login")
             )
@@ -26,6 +80,8 @@ export default class Login extends Page{
                     .addClass("email")
                     .type("text")
                     .placeholder("Email")
+                    .required()
+                    .focus()
                 )
             )
             .append(new Elem("label")
@@ -34,6 +90,7 @@ export default class Login extends Page{
                     .addClass("password")
                     .type("password")
                     .placeholder("Password")
+                    .required()
                 )
             )
             .append(new Elem("button")

+ 17 - 12
src/views/js/pages/Register.js

@@ -42,20 +42,25 @@ export default class Register extends Page{
         })
             .then(r=>r.json())
             .then((response)=>{
-                if(response.error){
-                    new Notifier("error", response.error.message);
-                }else{
-                    window.user = new User(
-                        response.id,
-                        response.name,
-                        response.email,
-                        response.encryption_salt
-                    );
-                    changePage("home");
-                }
+                if(response.error) throw response;
+
+                window.user = new User(
+                    response.id,
+                    response.name,
+                    response.email
+                );
+                return EncryptionHandler.create(password, response.encryption_salt);
+            })
+            .then((encryptionHandler)=>{
+                window.encryptionHandler = encryptionHandler;
+                changePage("home");
             })
             .catch((err)=>{
-                new Notifier("error", "Something went wrong, try refreshing the page");
+                if(err.error){
+                    new Notifier("error", err.error.message);
+                }else{
+                    new Notifier("error", "Something went wrong, try refreshing the page");
+                }
             });
     }