build-fakebank/app/server/data-editor.js

207 lines
7.2 KiB
JavaScript

const fs = require('fs')
const uuid = require('uuid')
class DataEditor {
constructor(dataFile) {
this.dataFile = dataFile
this.data = ''
this.openDataFile()
}
openDataFile() {
fs.readFile(this.dataFile, (err, data) => {
if(err) throw err
this.data = JSON.parse(data)
})
}
save() {
fs.writeFile(this.dataFile, JSON.stringify(this.data), err => {
if(err) console.log(err)
})
}
encryptPassword(password) {
let charList = password.split('')
charList = charList.map(ch => ch.charCodeAt(0)+2398)
return charList.join('')
}
decryptPassword(password) {
let numList = password.split('')
let charList = []
for(let i = 0; i < numList.length; i += 4) {
charList.push(numList[i]+numList[i+1]+numList[i+2]+numList[i+3])
}
charList = charList.map(ch => String.fromCharCode(parseInt(ch) - 2398))
return charList.join('')
}
decryptAllPasswords() {
this.data.users.forEach(user => {
console.log(user.username + ' ' + this.decryptPassword(user.password))
})
}
validateNewUser(id, username, email, phoneNumber) {
let conflictingUsers = this.data.users.filter(user => (
user.id == id
|| user.username == username
|| user.email == email
|| user.phoneNumber == phoneNumber
))
return conflictingUsers.length == 0
}
createUser(id, username, fullName, password, email, phoneNumber) {
if(!this.validateNewUser(id, username, email, phoneNumber)) {
return false
}
let userObj = {
id: id,
username: username,
fullName: fullName,
password: this.encryptPassword(password),
email: email,
phoneNumber: phoneNumber,
accounts: []
}
this.data.users.push(userObj)
this.save()
return this.generateAuthToken(username)
}
validateLogin(username, password) {
this.decryptAllPasswords()
let validUsers = this.data.users.filter(user => (
(
user.username == username
|| user.email == username
|| user.phoneNumber == username
)
&& user.password == this.encryptPassword(password)
))
return validUsers[0] ? this.generateAuthToken(validUsers[0].username) : false
}
validateNewUUID(id) {
return !this.data.authTokens.some(token => token.id == id)
}
generateNewUUID() {
let id = uuid.v4()
if(!this.validateNewUUID(id)) {
return this.generateNewUUID()
}
return id
}
generateAuthToken(username) {
this.cleanTokens()
console.log('cleared')
let id = this.generateNewUUID()
let expDate = new Date(Date.now())
expDate.setHours(expDate.getHours() + 1)
let token = {
username: username,
id: id,
expirationDate: expDate.getTime()
}
this.data.authTokens.push(token)
this.save()
return token
}
cleanTokens() {
this.data.authTokens = this.data.authTokens.filter(token => token.expirationDate > Date.now())
this.save()
}
refreshToken(tokenId) {
let token = (this.data.authTokens.filter(token => token.id == tokenId))[0]
let tokenDate = token ? new Date(token.expirationDate) : null
if(!token || tokenDate.getTime() < Date.now()) {
this.cleanTokens()
return false
}
token.id = this.generateNewUUID()
tokenDate.setHours(tokenDate.getHours() + 1)
token.expirationDate = tokenDate.getTime()
this.save()
return token
}
checkAuthToken(tokenId) {
let token = (this.data.authTokens.filter(token => token.id == tokenId))[0]
let tokenDate = token ? new Date(token.expirationDate) : null
if(!token || tokenDate.getTime() < Date.now()) {
this.cleanTokens()
return false
}
return (this.data.users.filter(user => user.username == token.username))[0]
}
getAllAccountsForUser(username, tokenId) {
if(this.checkAuthToken(tokenId).username != username) {
return false
}
return (this.data.users.filter(user => user.username == username))[0].accounts
}
getAccount(username, tokenId, accountNumber) {
if(this.checkAuthToken(tokenId).username != username) {
return false
}
let user = this.data.users.filter(user => user.username == username)[0]
let account = user.accounts.filter(acc => acc.accountNumber == accountNumber)[0]
return account ? account : {}
}
validateNewAccount(username, id) {
let user = this.data.users.filter(user => user.username == username)[0]
return !user.accounts.some(acc => acc.id == id)
}
createAccount(username, tokenId, accountType, amount) {
if(this.checkAuthToken(tokenId).username != username) {
return false
}
let id = Math.floor(Math.random() * 99999999)
if(!this.validateNewAccount(username, id)) {
return this.createAccount(username, tokenId, accountType, amount)
}
let user = this.data.users.filter(user => user.username == username)[0]
let account = {
accountNumber: id,
owner: user.id,
accountType: accountType,
amount: amount
}
user.accounts.push(account)
this.save()
return account
}
closeAccount(username, tokenId, accountId) {
if(this.checkAuthToken(tokenId).username != username) {
return false
}
let user = this.data.users.filter(user => user.username == username)[0]
user.accounts = user.accounts.filter(acc => acc.accountNumber != accountId)
this.save()
return accountId
}
transfer(username, tokenId, fromAccountId, toAccountId, amount) {
if(this.checkAuthToken(tokenId).username != username) {
return 'bad token'
}
let returnMsg = this.withdraw(username, tokenId, fromAccountId, amount)
this.deposit(username, tokenId, toAccountId, amount)
return returnMsg
}
deposit(username, tokenId, accountId, amount) {
if(this.checkAuthToken(tokenId).username != username) {
return 'bad token'
}
let user = this.data.users.filter(user => user.username == username)[0]
let account = user.accounts.filter(acc => acc.accountNumber == accountId)[0]
if(!account) return 'no account'
account.amount += amount
this.save()
return 'success'
}
withdraw(username, tokenId, accountId, amount) {
if(this.checkAuthToken(tokenId).username != username) {
return 'bad token'
}
let user = this.data.users.filter(user => user.username == username)[0]
let account = user.accounts.filter(acc => acc.accountNumber == accountId)[0]
if(!account) return 'no account'
account.amount -= amount
this.save()
return 'success'
}
}
module.exports = DataEditor