oak-general-business/lib/context/BackendRuntimeContext.js

258 lines
8.7 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.BackendRuntimeContext = void 0;
const assert_1 = require("oak-domain/lib/utils/assert");
const Exception_1 = require("../types/Exception");
const Exception_2 = require("oak-domain/lib/types/Exception");
const constants_1 = require("../constants");
const uuid_1 = require("oak-domain/lib/utils/uuid");
const Projection_1 = require("../types/Projection");
const wechatQrCode_1 = require("../aspects/wechatQrCode");
const oak_frontend_base_1 = require("oak-frontend-base");
const lodash_1 = require("oak-domain/lib/utils/lodash");
/**
* general数据结构要求的后台上下文
*/
class BackendRuntimeContext extends oak_frontend_base_1.BackendRuntimeContext {
application;
token;
amIRoot;
amIReallyRoot;
rootMode;
userId;
async refineOpRecords() {
for (const opRecord of this.opRecords) {
if (opRecord.a === 's') {
const { d } = opRecord;
for (const entity in d) {
if (entity === 'wechatQrCode') {
// todo 小程序码此时去微信服务器获得码数据
const wechatQrCodeListObj = d[entity];
for (const id in wechatQrCodeListObj) {
const wechatQrCodeData = wechatQrCodeListObj[id];
if (wechatQrCodeData.hasOwnProperty('buffer') &&
wechatQrCodeData.type === 'wechatMpWxaCode') {
const buffer = await (0, wechatQrCode_1.getMpUnlimitWxaCode)(id, this);
Object.assign(wechatQrCodeData, {
buffer,
});
}
}
}
else if (['application', 'system', 'platform'].includes(entity)) {
// todo 删除掉config中的敏感返回信息
}
}
}
}
}
async setTokenValue(tokenValue, userId) {
if (tokenValue) {
// 前台传递
const result = await this.select('token', {
data: {
id: 1,
ableState: 1,
user: {
id: 1,
userState: 1,
isRoot: 1,
},
userId: 1,
value: 1,
player: {
id: 1,
isRoot: 1,
},
},
filter: {
$or: [
{
value: tokenValue,
},
{
oldValue: tokenValue,
refreshedAt: {
$gte: Date.now() - 300 * 1000,
},
},
],
},
}, {
dontCollect: true,
blockTrigger: true,
});
if (result.length === 0) {
console.log(`构建BackendRuntimeContext对应tokenValue「${tokenValue}找不到相关的user`);
throw new Exception_1.OakTokenExpiredException();
}
const token = result[0];
if (token.ableState === 'disabled') {
console.log(`构建BackendRuntimeContext对应tokenValue「${tokenValue}已经被disable`);
throw new Exception_1.OakTokenExpiredException();
}
const { user, player } = token;
this.amIRoot = user?.isRoot;
this.amIReallyRoot = player?.isRoot;
this.token = token;
this.userId = token.userId;
return;
}
if (userId) {
// 若是后台环境用userId来查询处理
const [user] = await this.select('user', {
data: {
id: 1,
isRoot: 1,
},
filter: { id: userId },
}, { dontCollect: true });
(0, assert_1.assert)(user, '初始化context时有userId但查询不到user');
this.amIRoot = user.isRoot;
this.amIReallyRoot = user.isRoot;
this.userId = userId;
}
}
async setApplication(appId) {
const result = await this.select('application', {
data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection),
filter: {
id: appId,
},
}, {
dontCollect: true,
blockTrigger: true,
});
(0, assert_1.assert)(result.length > 0, `构建BackendRuntimeContext对应appId「${appId}」找不到application`);
this.application = result[0];
}
async initialize(data, later) {
await super.initialize(data);
if (data) {
const closeRootMode = this.openRootMode();
try {
const { a: appId, t: tokenValue, rm, userId } = data;
const promises = [];
if (appId) {
promises.push(this.setApplication(appId));
}
if (tokenValue || userId) {
promises.push(this.setTokenValue(tokenValue, userId));
}
if (promises.length > 0) {
await Promise.all(promises);
}
if (!rm) {
closeRootMode();
}
}
catch (err) {
closeRootMode();
throw err;
}
}
else {
// 否则是后台模式默认用root
this.rootMode = true;
}
}
getApplicationId() {
return this.application?.id;
}
getSystemId() {
return this.application?.systemId;
}
getApplication() {
return this.application;
}
openRootMode() {
if (this.rootMode) {
return () => undefined;
}
this.rootMode = true;
return () => (this.rootMode = false);
}
getTokenValue(allowUnloggedIn) {
if (this.rootMode) {
return constants_1.ROOT_TOKEN_ID;
}
if (!this.token && !allowUnloggedIn) {
throw new Exception_2.OakUnloggedInException();
}
return this.token?.value;
}
getToken(allowUnloggedIn) {
if (!this.token && !allowUnloggedIn) {
throw new Exception_2.OakUnloggedInException();
}
if (this.token) {
const { userState } = this.token.user;
if (['disabled', 'merged'].includes(userState) &&
!this.isReallyRoot()) {
throw new Exception_1.OakUserDisabledException();
}
}
return this.token;
}
getCurrentUserId(allowUnloggedIn) {
if (this.userId) {
return this.userId;
}
const token = this.getToken(allowUnloggedIn);
return token?.userId;
}
setCurrentUserId(userId) {
(0, assert_1.assert)(this.isReallyRoot);
this.userId = userId;
}
async getSerializedData() {
const data = await super.getSerializedData();
// 后台物化上下文直接存userId;
return {
...data,
a: this.application?.id,
rm: this.rootMode,
userId: this.getCurrentUserId(true),
};
}
isRoot() {
if (this.rootMode) {
return true;
}
return !!this.amIRoot;
}
isReallyRoot() {
return !!this.amIReallyRoot;
}
async sendMessage(data) {
return this.operate('message', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'create',
data,
}, {
dontCollect: true,
});
}
allowUserUpdate() {
if (this.isReallyRoot()) {
return true;
}
const userInfo = this.token?.user;
if (userInfo) {
const { userState } = userInfo;
if (userState === 'disabled') {
throw new Exception_1.OakUserDisabledException('您的帐号已经被禁用,请联系客服');
}
else if (['merged'].includes(userState)) {
throw new Exception_1.OakTokenExpiredException('您的登录状态有异常,请重新登录 ');
}
else {
(0, assert_1.assert)(userState === 'normal' || userState === 'shadow');
}
return true;
}
throw new Exception_2.OakUnloggedInException('您尚未登录');
}
}
exports.BackendRuntimeContext = BackendRuntimeContext;