iridium
Version:
A custom lightweight ORM for MongoDB designed for power-users
183 lines • 7.54 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const Promise = require("bluebird");
const Iridium = require("../iridium");
const iridium_1 = require("../iridium");
var settings = {};
let User = class User extends Iridium.Instance {
get username() {
return this._id;
}
static onCreating(user) {
var passwordTest = /(?=^.{8,}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*/;
if (!passwordTest.test(user.password || ""))
return Promise.reject(new Error("Password didn\"t meet the minimum safe password requirements. Passwords should be at least 8 characters long, and contain at least 3 of the following categories: lowercase letters, uppercase letters, numbers, characters"));
user.password = require("crypto").createHash("sha512").update(settings.security.salt).update(user.password).digest("hex");
_.defaults(user, {
type: "Player",
banned: false,
statistics: {
won: 0,
drawn: 0,
lost: 0,
incomplete: 0
},
skill: {
matchmaking: 0,
trend: 0,
level: 0,
xp: 0,
current_level: 0,
next_level: 1200
},
friends: [],
friend_requests: [],
pending_messages: [],
sessions: [],
last_seen: new Date()
});
}
get API() {
var $ = this;
return {
username: $.username,
fullname: $.fullname,
email: $.email,
banned: $.banned,
statistics: $.statistics,
skill: {
level: $.skill.level,
xp: $.skill.xp
},
friends: $.friends,
pending_messages: $.pending_messages,
last_seen: $.last_seen
};
}
setPassword(newPassword, callback) {
/// <summary>Updates the user's stored password hash</summary>
/// <param name="newPassword" type="String">The new password to use for the user</param>
/// <param name="callback" type="Function">A function to be called once the user's password has been updated</param>
var passwordTest = /(?=^.{8,}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*/;
if (!passwordTest.test(newPassword || ""))
return callback(new Error("Password didn\"t meet the minimum safe password requirements. Passwords should be at least 8 characters long, and contain at least 3 of the following categories: lowercase letters, uppercase letters, numbers, characters"));
var hashed = require("crypto").createHash("sha512").update(settings.security.salt).update(newPassword).digest("hex");
this.password = hashed;
this.save(callback);
}
checkPassword(password) {
/// <summary>Checks whether a given password is correct for a user's account</summary>
/// <param name="password" type="String">The password to validate against the user's password hash.</param>
/// <returns type="Boolean"/>
var hashed = require("crypto").createHash("sha512").update(settings.security.salt).update(password).digest("hex");
return hashed == this.password;
}
addFriend(friend, callback) {
this.save({ $push: { friends: friend } }, callback);
}
updateLevel() {
/// <summary>Update"s the user"s current level based on the amount of XP they have. Doesn't save the user instance.</summary>
// Amount of XP required per level starts at 1200, doubles for each consecutive level
// tf. XP_n = XP_nm1 + 1200 * 2^n
var remainingXP = this.skill.xp;
var previousLevelXP = 0;
var levelXP = 1200;
var level = 0;
for (; remainingXP >= levelXP; level++, previousLevelXP = levelXP, remainingXP -= levelXP, levelXP += 1200 * Math.pow(2, level))
;
this.skill.level = level;
this.skill.current_level = previousLevelXP;
this.skill.next_level = levelXP;
}
};
__decorate([
Iridium.Property(/^[a-z][a-z0-9_]{7,}$/)
], User.prototype, "_id", void 0);
__decorate([
iridium_1.Property(String)
], User.prototype, "fullname", void 0);
__decorate([
iridium_1.Property(/^.+@.+$/)
], User.prototype, "email", void 0);
__decorate([
iridium_1.Property("password")
], User.prototype, "password", void 0);
__decorate([
iridium_1.Property(/Player|Moderator|Admin/)
], User.prototype, "type", void 0);
__decorate([
iridium_1.Property(Boolean)
], User.prototype, "banned", void 0);
__decorate([
iridium_1.Property({
won: Number,
drawn: Number,
lost: Number,
incomplete: Number
})
], User.prototype, "statistics", void 0);
__decorate([
iridium_1.Property({
matchmaking: Number,
trend: Number,
level: Number,
xp: Number,
current_level: Number,
next_level: Number
})
], User.prototype, "skill", void 0);
__decorate([
iridium_1.Property([String])
], User.prototype, "friends", void 0);
__decorate([
iridium_1.Property([{
from: String,
time: Date,
message: String,
group: { $required: false, $type: String },
game: { $required: false, $type: String }
}])
], User.prototype, "pending_messages", void 0);
__decorate([
iridium_1.Property([String])
], User.prototype, "sessions", void 0);
__decorate([
iridium_1.Property([String])
], User.prototype, "friend_requests", void 0);
__decorate([
iridium_1.Property(Date)
], User.prototype, "last_seen", void 0);
User = __decorate([
Iridium.Collection("user"),
iridium_1.Index({ email: 1 }, { unique: true }),
iridium_1.Index({ sessions: 1 }, { sparse: true }),
iridium_1.Index({ "skill.xp": -1 }, { background: true }),
iridium_1.Validate("password", function (schema, data, path) {
// This should use something like zxcvbn to determine whether a password
// is strong enough for your use case.
return this.assert(typeof data === "string" && /^.{8,}$/.test(data), "Expected password to be at least 8 characters long.");
})
], User);
exports.User = User;
class Core extends Iridium.Core {
constructor() {
super(...arguments);
this.Users = new Iridium.Model(this, User);
}
}
let core = new Core("mongodb://localhost/iridium_users");
core.Users.findOne().then(function (user) {
if (!user)
throw new Error("Couldn't find a user");
if (user.checkPassword("test"))
return true;
return false;
});
//# sourceMappingURL=UserModel.js.map