import js_sha from 'js-sha256';
import path from 'path';
import fs from 'fs';

/*
 * This file serves as a way to implement an authentication server.
 * The current implementation serves as a simple example of local authentication.
 * ap-npm was created to be easily extensible (which alternatives weren't).
 * We promote implementing a proper authentication method.
 */
export default class {
  constructor(config) {
    this.dbLocation = path.join(config.workDir, 'db');
    this.initUserDB();
    this.settings = config.auth;
  }

  userLogin(username, password, email) {
    return new Promise((resolve) => {
      let userLoggedIn;
      try {
        userLoggedIn = this.users[username].password === js_sha.sha256(password) && this.users[username].email === email;

        if (userLoggedIn) {
          resolve(userLoggedIn);
        }
      } catch (err) {
        resolve(false);
      }
    }).catch(() => {
      return false;
    });
  }

  userAdd(username, password, email) {
    return new Promise((resolve) => {
      if (this.settings.register) {
        if (typeof (this.users[username]) === "object") {
          resolve(false);
        } else {
          this.users[username] = {
            username: username,
            password: js_sha.sha256(password),
            email: email,
          };
          this.updateUserDB();
          this.initUserDB();

          // Success
          resolve(true);
        }
      } else {
        resolve(false);
      }
    }).catch(() => {
      return false;
    });
  }

  /*
  * Doesn't get used yet, npm doesn't implement it and neither have we (yet)
  */
  userRemove(username, password) {
    return new Promise((resolve, reject) => {
      if (this.settings.remove) {
        if (this.users[username] && this.users[username][password] === js_sha.sha256(password)) {
          this.users.remove(username);
          this.updateUserDB();

          // Success
          resolve(true);
        }
      } else {
        reject("Not allowed to remove users");
      }
    }).catch(() => {
      return false;
    });
  }


  // Just here for local auth
  initUserDB() {
    let user_db_path = path.join(this.dbLocation, 'user_db.json');

    if (!fs.existsSync(this.dbLocation)) {
      try {
        fs.mkdirSync(this.dbLocation, '0777', true);
      } catch (err) {
        console.log("Error making userDB folder (" + this.dbLocation + "), ap-npm might malfunction");
      }
    }
    try {
      let user_db_json = fs.readFileSync(user_db_path, 'utf8');
      this.users = JSON.parse(user_db_json);
    } catch (err) {
      this.users = {};
    }
  }

  // Just here for local auth
  updateUserDB() {
    let user_db_path = path.join(this.dbLocation, 'user_db.json');
    fs.writeFileSync(user_db_path, JSON.stringify(this.users, null, 2), { 'mode': '0777' });
    this.initUserDB();
  }
}
@@ -725,16 +725,26 @@
 word) &&
+%0A         
  this.us
@@ -774,16 +774,16 @@
  email;%0A
-
 %0A       
@@ -1382,37 +1382,16 @@
 rDB();%0A%0A
-          // Success%0A
         
@@ -1525,16 +1525,17 @@
 %0A  /*%0A  
+ 
 * Doesn'
@@ -1601,16 +1601,17 @@
 e (yet)%0A
+ 
   */%0A  u
@@ -2189,256 +2189,8 @@
 n');
-%0A%0A    if (!fs.existsSync(this.dbLocation)) %7B%0A      try %7B%0A        fs.mkdirSync(this.dbLocation, '0777', true);%0A      %7D catch (err) %7B%0A        console.log(%22Error making userDB folder (%22 + this.dbLocation + %22), ap-npm might malfunction%22);%0A      %7D%0A    %7D
 %0A   
@@ -2548,17 +2548,16 @@
 l, 2), %7B
- 
 'mode': 
@@ -2562,17 +2562,16 @@
 : '0777'
- 
 %7D);%0A    

Remove storage check from json-db and format code