oak-general-business/lib/checkers/user.js

205 lines
8.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserCheckers = void 0;
const tslib_1 = require("tslib");
const relation_1 = require("oak-domain/lib/store/relation");
const types_1 = require("oak-domain/lib/types");
const filter_1 = require("oak-domain/lib/store/filter");
const validator_1 = require("oak-domain/lib/utils/validator");
const executor_1 = require("oak-domain/lib/utils/executor");
const assert_1 = tslib_1.__importDefault(require("assert"));
const Exception_1 = require("../types/Exception");
const user_1 = require("../utils/user");
const checkers = [
{
type: 'row',
action: 'remove',
entity: 'user',
filter: {
userState: 'shadow',
}
},
{
type: 'logical',
action: ['remove', 'disable', 'enable'],
entity: 'user',
checker: (operation, context) => {
// 只有root才能进行操作
if (!context.isRoot()) {
throw new types_1.OakOperationUnpermittedException('user', { id: 'disable', action: 'disable', data: {} }, context.getCurrentUserId());
}
}
},
{
type: 'data',
action: 'grant',
entity: 'user',
checker: (data) => {
if (Object.keys(data).filter(ele => !ele.includes('$')).length > 0) {
throw new types_1.OakInputIllegalException('user', Object.keys(data), '授权不允许传入其它属性');
}
}
},
{
type: 'row',
action: 'disable',
entity: 'user',
filter: {
isRoot: false,
},
errMsg: '不能禁用root用户',
},
{
type: 'logicalData',
action: 'verify',
entity: 'user',
checker(operation, context) {
const { data, filter } = operation;
const { idCardType, idNumber, extraFile$entity: photos, name } = data;
(0, assert_1.default)(typeof filter.id === 'string');
const system = context.getApplication().system;
const { config } = system;
return (0, executor_1.pipeline)(() => context.select('user', {
data: {
id: 1,
name: 1,
idCardType: 1,
idNumber: 1,
extraFile$entity: {
$entity: 'extraFile',
data: {
id: 1,
tag1: 1,
tag2: 1,
}
},
},
filter: {
id: filter.id,
}
}, {}), (users) => {
const [user] = users;
const idCardType = data.idCardType || user.idCardType;
const idNumber = data.idNumber || user.idNumber;
const name = data.name || user.name;
const photo1 = data.extraFile$entity && data.extraFile$entity.find(ele => ele.action === 'create' && ele.data.tag1 === idCardType &&
ele.data.tag2 === 'file1') || user.extraFile$entity && user.extraFile$entity.find(ele => ele.tag1 === idCardType && ele.tag2 === 'file1');
const photo2 = data.extraFile$entity && data.extraFile$entity.find(ele => ele.action === 'create' && ele.data.tag1 === idCardType &&
ele.data.tag2 === 'file2') || user.extraFile$entity && user.extraFile$entity.find(ele => ele.tag1 === idCardType && ele.tag2 === 'file2');
if (!name) {
throw new types_1.OakInputIllegalException('user', ['name'], 'error::user.verifyNameEmpty');
}
if (!idCardType) {
throw new types_1.OakInputIllegalException('user', ['idCardType'], 'error::user.verifyIdCardTypeEmpty');
}
if (!idNumber) {
throw new types_1.OakInputIllegalException('user', ['idNumber'], 'error::user.verifyIdNumberTypeEmpty');
}
if (config.App.needUploadIDCardPhoto) {
if (!photo1) {
throw new types_1.OakInputIllegalException('user', ['extraFile$entity'], 'error::user.verifyLackOfPhoto1');
}
if (!photo2) {
throw new types_1.OakInputIllegalException('user', ['extraFile$entity'], 'error::user.verifyLackOfPhoto2');
}
}
switch (idCardType) {
case 'ID-Card': {
if (!(0, validator_1.isIdCardNumber)(idNumber)) {
throw new types_1.OakInputIllegalException('user', ['idNumber'], 'error::user.verifyIdNumberIllegal');
}
break;
}
case 'Mainland-passport': {
if (!(0, validator_1.isHkCardNumber)(idNumber) && (0, validator_1.isTwCardNumber)(idNumber) && (0, validator_1.isAmCardNumber)(idNumber)) {
throw new types_1.OakInputIllegalException('user', ['idNumber'], 'error::user.verifyIdNumberIllegal');
}
break;
}
case 'passport': {
if (!(0, validator_1.isPassportNumber)(idNumber)) {
throw new types_1.OakInputIllegalException('user', ['idNumber'], 'error::user.verifyIdNumberIllegal');
}
break;
}
}
});
}
},
{
type: 'row',
entity: 'user',
action: 'update',
filter(operation, context) {
const isRoot = context.isRoot();
if (isRoot) {
return undefined;
}
const { data } = operation;
if (data?.hasOwnProperty('password')) {
return (0, user_1.getUserSafetyFilter)(context);
}
},
err: Exception_1.OakHasToVerifyPassword,
},
{
type: 'row',
entity: 'user',
action: 'update',
filter(operation, context) {
const isRoot = context.isRoot();
if (isRoot) {
return undefined;
}
const { data } = operation;
if (data?.hasOwnProperty('name') || data?.hasOwnProperty('idCardType')
|| data?.hasOwnProperty('idNumber') || data?.hasOwnProperty('gender')
|| data?.hasOwnProperty('birth')) {
return {
idState: {
$nin: ['verified'],
},
};
}
},
err: Exception_1.OakHasToVerifyPassword,
}
];
exports.default = checkers;
exports.UserCheckers = [
{
entity: 'user',
action: 'update',
type: 'logical',
checker: (operation, context) => {
// 在大部分应用中除了root其他人不应该有权利更新其他人信息但是shadow用户应当除外
// 但这些条件不一定对所有的应用都成立应用如果有更复杂的用户相互更新策略就不要引入这个checker
// 这也是个例子如何对user这样的特殊对象进行权限控制
const userId = context.getCurrentUserId();
if (context.isRoot()) {
return;
}
const { filter, data } = operation;
for (const attr in data) {
const rel = (0, relation_1.judgeRelation)(context.getSchema(), 'user', attr);
if (rel !== 1) {
throw new types_1.OakOperationUnpermittedException('user', operation, context.getCurrentUserId(), '您不能更新他人信息');
}
}
const result = (0, filter_1.checkFilterContains)('user', context, {
id: userId,
}, filter, true);
if (result instanceof Promise) {
return result.then((r) => {
if (!r) {
throw new types_1.OakOperationUnpermittedException('user', operation, context.getCurrentUserId(), '您不能更新他人信息');
}
});
}
if (!result) {
throw new types_1.OakOperationUnpermittedException('user', operation, context.getCurrentUserId(), '您不能更新他人信息');
}
},
}
];