-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Account.js
164 lines (146 loc) · 3.7 KB
/
Account.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
'use strict';
const bcrypt = require('bcryptjs');
const Data = require('./Data');
/**
* Representation of a player's account
*
* @property {String} username Player's username
* @property {Array<Object>} characters Array of this account's characters and their active status
* @property {String} password Hashed password
* @property {Boolean} active Whether this account is active
* @property {Boolean} banned Whether this account is banned
*
* @mixes Metadatable
*/
class Account {
constructor(data) {
this.username = data.username;
this.characters = data.characters || [];
this.password = data.password;
this.active = data.active;
this.banned = data.banned || false;
// Arbitrary data bundles are free to shove whatever they want in
// WARNING: values must be JSON.stringify-able
this.metadata = data.metadata || {};
}
/**
* Create a hashed password from a provided password string
* @private
* @param {String} password
* @return {String} Hashed password
*/
_hashPassword(password) {
const salt = bcrypt.genSaltSync(10);
return bcrypt.hashSync(password, salt);
}
/**
* Return this account's username
* @return {String} username
*/
getUsername() {
return this.username;
}
/**
* Add an object representing a character to this account
* @param {String} name character's name
*/
addCharacter(name) {
this.characters.push({ name: name, active: true});
}
/**
* Whether this account has a specifically named character
* @param {String} name character's name
* @return {boolean}
*/
hasCharacter(name) {
return this.characters.find(c => c.name === name);
}
/**
* Toggle a character on this account as inactive
* @param {String} name character's name
*/
deactivateCharacter(name) {
var picked = this.characters.find(c => c.name === name);
picked.active = false;
this.save();
}
/**
* Toggle a character on this account as active
* @param {string} name character's name
*/
activateCharacter(name) {
var picked = this.characters.find(c => c.name === name);
picked.active = false;
this.save();
}
/**
* Set a hashed password for this account based on a provided string
* @param {String} password Unhashed password
*/
setPassword(password) {
this.password = this._hashPassword(password);
this.save();
}
/**
* Check provided password against this account's hashed password
* @param {String} password Unhashed password to check against this account's password
* @return {Boolean}
*/
checkPassword(password) {
return bcrypt.compareSync(password, this.password);
}
/**
* Save the account to disk
* @param {function} callback
*/
save(callback) {
Data.save('account', this.username, this.serialize(), callback);
}
/**
* Toggle this account to be banned
*/
ban() {
this.banned = true;
this.save();
}
/**
* Toggle this account to be unbanned
*/
unban() {
this.banned = false;
this.save();
}
/**
* Toggle this account as inactive
*/
deactivateAccount() {
this.characters.forEach(char => {
this.deactivateCharacter(char.name);
});
this.active = false;
this.save();
}
/**
* Toggle this account as active
*/
activateAccount() {
this.active = true;
this.save();
}
/**
* Gather data to be persisted
* @return {Object}
*/
serialize() {
let data = {
username: this.username,
characters: this.characters,
password: this.password,
active: this.active,
banned: this.banned,
metadata: this.metadata
};
return data;
}
}
module.exports = Account;