2019-05-13 20:14:39 +08:00

150 lines
4.3 KiB
JavaScript

'use strict';
import mongoose from 'mongoose';
import passportLocalMongoose from 'passport-local-mongoose';
const AdminActionSchema = new mongoose.Schema({
_id: {type: String, required: true},
name: {type: String, required: true},
paths: [{
method: String,
path: String,
}],
deleted: {type: Boolean, default: false},
deleted_time: {type: Date},
}, {
collection: 'admin_actions',
timestamps: true,
});
const AdminAction = mongoose.model('AdminAction', AdminActionSchema);
const AdminRoleSchema = new mongoose.Schema({
_id: {type: String, required: true},
name: {type: String, required: true},
permissions: [{type: String, ref: 'AdminAction'}],
deleted: {type: Boolean, default: false},
deleted_time: {type: Date},
}, {
collection: 'admin_roles',
timestamps: true,
});
const AdminRole = mongoose.model('AdminRole', AdminRoleSchema);
/**
* 用户表不需要添加 timestamps: true
*
* 因为 createdAt 可以从ObjectID中提取, updatedAt 会因为last和ateemps随时变更,
* 如果需要跟踪关键数据的变更时间, 应添加独立自管的 updatedAt,
* 或者直接使用 immutable data 追踪变化
*/
const AdminSchema = new mongoose.Schema({
username: String,
password: String,
roles: [{type: String, ref: 'AdminRole'}],
permissions: [{type: String, ref: 'AdminAction'}],
games: [{type: String}],
profile: {
name: String,
gender: String,
},
comment: String,
createdBy: {type: String, ref: 'Admin', required: true},
lastModifiedBy: {type: String, ref: 'Admin', required: true},
locked: {type: Boolean, default: false},
locked_time: {type: Date},
deleted: {type: Boolean, default: false},
delete_time: {type: Date},
lastLogin: Date, // passport-local-mongoose 添加的 last 字段记录的是最后一次登录尝试,
// 而不是最后一次成功登录
});
AdminSchema.virtual('createdAt').get(function() {
return this._id.getTimestamp();
});
/**
* TODO this is far away from elegant, maybe change it later.
*/
AdminSchema.virtual('hasSysAdmin').get(function() {
return this.roles.includes('sys_admin');
});
AdminSchema.virtual('hasNavSystem').get(function() {
let yes = this.roles.includes('admin');
yes = yes || this.permissions.includes('edit_accounts');
return yes;
});
AdminSchema.virtual('hasNavGameApi').get(function() {
let yes = this.roles.includes('admin');
yes = yes || this.roles.includes('game_api_manager');
yes = yes || this.permissions.includes('edit_game_apis');
return yes;
});
AdminSchema.virtual('hasNavRedis').get(function() {
let yes = this.roles.includes('admin');
yes = yes || this.roles.includes('redis_manager');
yes = yes || this.permissions.includes('edit_redis');
return yes;
});
AdminSchema.virtual('hasNavWechat').get(function() {
let yes = this.roles.includes('admin');
yes = yes || this.roles.includes('wechat_manager');
yes = yes || this.permissions.includes('edit_wechat');
return yes;
});
AdminSchema.virtual('hasNavGM').get(function() {
let yes = this.roles.includes('admin');
yes = yes || this.roles.includes('gm_manager');
yes = yes || this.permissions.includes('edit_gm');
return yes;
});
AdminSchema.virtual('hasNavTool').get(function() {
let yes = this.roles.includes('admin');
yes = yes || this.roles.includes('tool_manager');
yes = yes || this.permissions.includes('edit_tool');
return yes;
});
AdminSchema.virtual('hasAdminRole').get(function() {
return this.roles.includes('admin');
});
AdminSchema.methods.checkGame = function(gid) {
let yes = this.roles.includes('admin');
yes = yes || this.games.includes(gid);
return yes;
};
AdminSchema.plugin(passportLocalMongoose,
{
limitAttempts: true,
usernameLowerCase: true,
maxAttempts: 10,
errorMessages: {
MissingPasswordError: '请输入密码',
AttemptTooSoonError: '您的账户当前被锁定,请稍后再试',
TooManyAttemptsError: '您的账户因错误登录次数太多而被锁定',
NoSaltValueStoredError: 'Authentication not possible. No salt value stored',
IncorrectPasswordError: '用户名或密码错误',
IncorrectUsernameError: '用户名或密码错误',
MissingUsernameError: '请输入用户名',
UserExistsError: '您输入的用户名已被使用',
},
});
const Admin = mongoose.model('Admin', AdminSchema);
export {Admin, AdminRole, AdminAction};