diff --git a/es/aspects/token.js b/es/aspects/token.js
index 9ccc91f25..13e01d139 100644
--- a/es/aspects/token.js
+++ b/es/aspects/token.js
@@ -536,23 +536,9 @@ export async function loginByMobile(params, context) {
}
export async function verifyPassword(params, context) {
const { password } = params;
- const systemId = context.getSystemId();
- const [pwdPassport] = await context.select('passport', {
- data: {
- id: 1,
- systemId: 1,
- config: 1,
- type: 1,
- enabled: 1,
- },
- filter: {
- systemId,
- enabled: true,
- type: 'password',
- }
- }, { forUpdate: true });
- // assert(pwdPassport);
- const pwdMode = pwdPassport?.config?.mode ?? 'all';
+ const { system } = context.getApplication();
+ const pwdConfig = system?.config.Password;
+ const pwdMode = pwdConfig?.mode ?? 'all';
let pwdFilter = {};
if (pwdMode === 'all') {
pwdFilter = {
@@ -664,13 +650,15 @@ export async function loginByAccount(params, context) {
id: 1,
type: 1,
systemId: 1,
- }
+ },
+ allowPwd: 1,
},
filter: {
passport: {
systemId,
},
applicationId,
+ allowPwd: true,
}
}, {
dontCollect: true,
@@ -761,13 +749,15 @@ export async function loginByAccount(params, context) {
id: 1,
type: 1,
systemId: 1,
- }
+ },
+ allowPwd: 1,
},
filter: {
passport: {
systemId,
},
applicationId,
+ allowPwd: true,
}
}, {
dontCollect: true,
@@ -875,29 +865,9 @@ export async function loginByAccount(params, context) {
}
};
const closeRootMode = context.openRootMode();
- const application = context.getApplication();
- const [applicationPassport] = await context.select('applicationPassport', {
- data: {
- id: 1,
- passportId: 1,
- passport: {
- id: 1,
- config: 1,
- type: 1,
- },
- applicationId: 1,
- },
- filter: {
- applicationId: application?.id,
- passport: {
- type: 'password',
- },
- }
- }, {
- dontCollect: true,
- });
- // assert(applicationPassport?.passport);
- const pwdMode = applicationPassport?.passport?.config?.mode ?? 'all';
+ const { system } = context.getApplication();
+ const pwdConfig = system?.config.Password;
+ const pwdMode = pwdConfig?.mode ?? 'all';
let pwdFilter = {}, updateData = {};
if (pwdMode === 'all') {
pwdFilter = {
@@ -2546,8 +2516,8 @@ export async function refreshToken(params, context) {
// 只有server模式去刷新token
// 'development' | 'production' | 'staging'
const intervals = {
- development: 7200 * 1000,
- staging: 600 * 1000,
+ development: 7200 * 1000, // 2小时
+ staging: 600 * 1000, // 十分钟
production: 600 * 1000, // 十分钟
};
let applicationId = token.applicationId;
diff --git a/es/components/changePassword/byMobile/index.d.ts b/es/components/changePassword/byMobile/index.d.ts
index 9e6eb4aca..9b24ef2db 100644
--- a/es/components/changePassword/byMobile/index.d.ts
+++ b/es/components/changePassword/byMobile/index.d.ts
@@ -1,3 +1,2 @@
-///
declare const _default: (props: import("oak-frontend-base").ReactComponentProps) => React.ReactElement;
export default _default;
diff --git a/es/components/changePassword/byMobile/index.js b/es/components/changePassword/byMobile/index.js
index 0a7382f5d..6c8ba5328 100644
--- a/es/components/changePassword/byMobile/index.js
+++ b/es/components/changePassword/byMobile/index.js
@@ -54,9 +54,8 @@ export default OakComponent({
lifetimes: {
async ready() {
const lastSendAt = await this.load(SEND_KEY);
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig = applicationPassports.find((ele) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/es/components/changePassword/byPassword/index.d.ts b/es/components/changePassword/byPassword/index.d.ts
index 9e6eb4aca..9b24ef2db 100644
--- a/es/components/changePassword/byPassword/index.d.ts
+++ b/es/components/changePassword/byPassword/index.d.ts
@@ -1,3 +1,2 @@
-///
declare const _default: (props: import("oak-frontend-base").ReactComponentProps) => React.ReactElement;
export default _default;
diff --git a/es/components/changePassword/byPassword/index.js b/es/components/changePassword/byPassword/index.js
index 435ebdf71..023a58537 100644
--- a/es/components/changePassword/byPassword/index.js
+++ b/es/components/changePassword/byPassword/index.js
@@ -23,9 +23,8 @@ export default OakComponent({
},
lifetimes: {
async ready() {
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig = applicationPassports.find((ele) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/es/components/config/style/platform/index.d.ts b/es/components/config/style/platform/index.d.ts
index d8ca7e5a9..9224d2cdc 100644
--- a/es/components/config/style/platform/index.d.ts
+++ b/es/components/config/style/platform/index.d.ts
@@ -1,7 +1,7 @@
import { Style } from '../../../../types/Style';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps) => React.ReactElement;
diff --git a/es/components/config/upsert/index.d.ts b/es/components/config/upsert/index.d.ts
index 9bf014f88..a4b61c5c2 100644
--- a/es/components/config/upsert/index.d.ts
+++ b/es/components/config/upsert/index.d.ts
@@ -1,7 +1,7 @@
import { Config } from '../../../types/Config';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps) => React.ReactElement;
diff --git a/es/components/config/upsert/password/index.d.ts b/es/components/config/upsert/password/index.d.ts
new file mode 100644
index 000000000..424f55446
--- /dev/null
+++ b/es/components/config/upsert/password/index.d.ts
@@ -0,0 +1,7 @@
+import React from 'react';
+import { Config } from '../../../../types/Config';
+export default function Security(props: {
+ password: Required['Password'];
+ setValue: (path: string, value: any) => void;
+ setValues: (value: Record) => void;
+}): React.JSX.Element;
diff --git a/es/components/config/upsert/password/index.js b/es/components/config/upsert/password/index.js
new file mode 100644
index 000000000..529d0d9cf
--- /dev/null
+++ b/es/components/config/upsert/password/index.js
@@ -0,0 +1,78 @@
+import React, { useEffect, useState } from 'react';
+import { Col, Divider, Input, Form, Space, Radio, InputNumber, Switch, } from 'antd';
+import Styles from './web.module.less';
+import EditorRegexs from '../../../passport/password/editorRegexs';
+export default function Security(props) {
+ const { password, setValue, setValues } = props;
+ const { mode, min, max, verify, regexs, tip } = password || {};
+ const [newTip, setNewTip] = useState('');
+ useEffect(() => {
+ const { password } = props;
+ if (!password.mode) {
+ setValues({
+ mode: 'all',
+ min: 8,
+ max: 24,
+ });
+ }
+ }, [password]);
+ useEffect(() => {
+ if (tip && !newTip) {
+ setNewTip(tip);
+ }
+ }, [tip]);
+ return (
+
+
+ 密码设置
+
+
+ {
+ const { value } = target;
+ setValue('mode', value);
+ }} value={mode}>
+ 明文与SHA1加密
+ 仅明文
+ 仅SHA1加密
+
+
+
+
+ {
+ setValue('min', value);
+ }}/>
+ ~
+ {
+ setValue('max', value);
+ }}/>
+
+
+
+
+ {
+ setValue('verigy', checked);
+ }}/>
+
+
+ <>
+ {!!verify ? (<>
+ {
+ setValue('regexs', regexs);
+ }}/>
+ >) : (暂未启用正则校验,无需设置
)}
+ >
+
+
+ {
+ setNewTip(e.target.value);
+ }} onBlur={() => {
+ if (newTip && newTip !== tip) {
+ setValue('tip', newTip);
+ }
+ }}/>
+
+
+
+ );
+}
diff --git a/es/components/config/upsert/password/web.module.less b/es/components/config/upsert/password/web.module.less
new file mode 100644
index 000000000..7fa576eed
--- /dev/null
+++ b/es/components/config/upsert/password/web.module.less
@@ -0,0 +1,16 @@
+
+.label {
+ color: var(--oak-text-color-primary);
+ font-size: 28px;
+ line-height: 36px;
+}
+
+.tips {
+ color: var(--oak-text-color-placeholder);
+ font-size: 12px;
+}
+
+.title {
+ margin-bottom: 0px;
+ margin-top:36px;
+}
\ No newline at end of file
diff --git a/es/components/config/upsert/web.pc.js b/es/components/config/upsert/web.pc.js
index 3167e78a3..5a0e68990 100644
--- a/es/components/config/upsert/web.pc.js
+++ b/es/components/config/upsert/web.pc.js
@@ -9,10 +9,11 @@ import Sms from './sms/index';
import Email from './email/index';
import Basic from './basic/index';
import Security from './security/index';
+import Password from './password/index';
export default function Render(props) {
const { entity, name, currentConfig, dirty } = props.data;
const { resetConfig, updateConfig, setValue, setValues, removeItem, cleanKey, t } = props.methods;
- const { Account: account, Cos: cos, Map: map, Live: live, Sms: sms, App: app, Emails: emails, Security: security, } = currentConfig || {};
+ const { Account: account, Cos: cos, Map: map, Live: live, Sms: sms, App: app, Emails: emails, Security: security, Password: password, } = currentConfig || {};
return (<>
@@ -84,6 +85,15 @@ export default function Render(props) {
});
}}/>),
},
+ {
+ key: '密码设置',
+ label: '密码设置',
+ children: ( setValue(`Password.${path}`, value)} setValues={(value) => {
+ setValues({
+ Password: value
+ });
+ }}/>),
+ },
]}>
>);
diff --git a/es/components/user/password/update/index.js b/es/components/user/password/update/index.js
index f532eb4fb..0cec4926e 100644
--- a/es/components/user/password/update/index.js
+++ b/es/components/user/password/update/index.js
@@ -34,9 +34,8 @@ export default OakComponent({
},
lifetimes: {
async ready() {
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig = applicationPassports.find((ele) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/es/components/user/password/verify/index.d.ts b/es/components/user/password/verify/index.d.ts
index c5fb2e667..721288d6b 100644
--- a/es/components/user/password/verify/index.d.ts
+++ b/es/components/user/password/verify/index.d.ts
@@ -1,4 +1,4 @@
declare const _default: (props: import("oak-frontend-base").ReactComponentProps void) | undefined;
+ onVerified: undefined | (() => void);
}>) => React.ReactElement;
export default _default;
diff --git a/es/components/user/password/verify/index.js b/es/components/user/password/verify/index.js
index 1c7bd268e..752bed879 100644
--- a/es/components/user/password/verify/index.js
+++ b/es/components/user/password/verify/index.js
@@ -11,9 +11,8 @@ export default OakComponent({
lifetimes: {
async ready() {
this.features.token.getToken();
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig = applicationPassports.find((ele) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
this.setState({
mode,
diff --git a/es/components/user/password/verify/web.d.ts b/es/components/user/password/verify/web.d.ts
index cb271e15f..8c7e08cdd 100644
--- a/es/components/user/password/verify/web.d.ts
+++ b/es/components/user/password/verify/web.d.ts
@@ -1,4 +1,3 @@
-///
import { WebComponentProps } from "oak-frontend-base";
import { EntityDict } from "../../../../oak-app-domain";
export default function Render(props: WebComponentProps
import { WebComponentProps } from "oak-frontend-base";
import { EntityDict } from "../../../../oak-app-domain";
export default function Render(props: WebComponentProps(props: ReactComponentProps) => React.ReactElement;
export default _default;
diff --git a/es/components/userRelation/upsert/byUser/index.d.ts b/es/components/userRelation/upsert/byUser/index.d.ts
index 57ff8d988..4940119bf 100644
--- a/es/components/userRelation/upsert/byUser/index.d.ts
+++ b/es/components/userRelation/upsert/byUser/index.d.ts
@@ -4,7 +4,7 @@ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
declare const _default: (props: ReactComponentProps) => React.ReactElement;
export default _default;
diff --git a/es/components/userRelation/upsert/byUserEntityGrant/index.d.ts b/es/components/userRelation/upsert/byUserEntityGrant/index.d.ts
index 5c6e1bdab..f72c8f3fc 100644
--- a/es/components/userRelation/upsert/byUserEntityGrant/index.d.ts
+++ b/es/components/userRelation/upsert/byUserEntityGrant/index.d.ts
@@ -7,12 +7,12 @@ declare const _default: void) | undefined;
+ rule: EntityDict["userEntityGrant"]["Schema"]["rule"];
+ ruleOnRow: EntityDict["userEntityGrant"]["OpSchema"]["ruleOnRow"];
+ onUserEntityGrantCreated?: (id: string) => void;
}>) => React.ReactElement;
export default _default;
diff --git a/es/components/userRelation/upsert/index.d.ts b/es/components/userRelation/upsert/index.d.ts
index 924306f4c..bfce90975 100644
--- a/es/components/userRelation/upsert/index.d.ts
+++ b/es/components/userRelation/upsert/index.d.ts
@@ -7,8 +7,8 @@ declare const _default: ;
- mode: 'byMobile' | 'byUserEntityGrant' | 'byEmail';
+ passwordRequired?: boolean;
+ disabledMethods: Array<"email" | "mobile" | "userEntityGrant">;
+ mode: "byMobile" | "byUserEntityGrant" | "byEmail";
}>) => React.ReactElement;
export default _default;
diff --git a/es/components/userRelation/upsert/onUser/index.d.ts b/es/components/userRelation/upsert/onUser/index.d.ts
index cafe99e04..1f0ec1ff8 100644
--- a/es/components/userRelation/upsert/onUser/index.d.ts
+++ b/es/components/userRelation/upsert/onUser/index.d.ts
@@ -2,7 +2,7 @@ import { EntityDict } from '../../../../oak-app-domain';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps void;
passwordRequired: boolean;
diff --git a/es/components/userRelation/upsert/onUser/index.js b/es/components/userRelation/upsert/onUser/index.js
index 370179a1d..88bae726e 100644
--- a/es/components/userRelation/upsert/onUser/index.js
+++ b/es/components/userRelation/upsert/onUser/index.js
@@ -84,9 +84,8 @@ export default OakComponent({
},
lifetimes: {
async ready() {
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig = applicationPassports.find((ele) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/es/components/userRelation/upsert/onUser/userRelation/index.d.ts b/es/components/userRelation/upsert/onUser/userRelation/index.d.ts
index 5db0a88be..3ce27eed3 100644
--- a/es/components/userRelation/upsert/onUser/userRelation/index.d.ts
+++ b/es/components/userRelation/upsert/onUser/userRelation/index.d.ts
@@ -2,6 +2,6 @@ import { EntityDict } from '../../../../../oak-app-domain';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps) => React.ReactElement;
export default _default;
diff --git a/es/types/Config.d.ts b/es/types/Config.d.ts
index 36e54fe4a..9a713bf07 100644
--- a/es/types/Config.d.ts
+++ b/es/types/Config.d.ts
@@ -151,6 +151,14 @@ export type EmailConfig = {
name?: string;
secure?: boolean;
};
+export type PasswordConfig = {
+ mode?: 'all' | 'plain' | 'sha1';
+ min?: number;
+ max?: number;
+ verify?: boolean;
+ regexs?: string[];
+ tip?: string;
+};
export type QrCodeType = 'wechatMpDomainUrl' | 'wechatMpWxaCode' | 'wechatPublic' | 'wechatPublicForMp' | 'webForWechatPublic';
export type Config = {
Account?: {
@@ -202,6 +210,7 @@ export type Config = {
level?: 'weak' | 'medium' | 'strong';
passwordVerifyGap?: number;
};
+ Password?: PasswordConfig;
};
export type AccountOrigin = 'ali' | 'tencent' | 'qiniu' | 'amap' | 'ctyun' | 'local' | 's3';
export type CosOrigin = 'qiniu' | 'wechat' | 'ctyun' | 'aliyun' | 'tencent' | 'local' | 'unknown' | 's3';
diff --git a/lib/aspects/token.js b/lib/aspects/token.js
index 120cfba2b..6a82a9d86 100644
--- a/lib/aspects/token.js
+++ b/lib/aspects/token.js
@@ -1,6 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-exports.loginWebByMpToken = exports.refreshToken = exports.wakeupParasite = exports.logout = exports.getWechatMpUserPhoneNumber = exports.switchTo = exports.sendCaptchaByEmail = exports.sendCaptchaByMobile = exports.syncUserInfoWechatMp = exports.loginWechatMp = exports.loginWechat = exports.loginWechatNative = exports.loginByWechat = exports.refreshWechatPublicUserInfo = exports.setUserAvatarFromWechat = exports.bindByEmail = exports.bindByMobile = exports.loginByEmail = exports.loginByAccount = exports.verifyPassword = exports.loginByMobile = exports.loadTokenInfo = exports.setUpTokenAndUser = void 0;
+exports.setUpTokenAndUser = setUpTokenAndUser;
+exports.loadTokenInfo = loadTokenInfo;
+exports.loginByMobile = loginByMobile;
+exports.verifyPassword = verifyPassword;
+exports.loginByAccount = loginByAccount;
+exports.loginByEmail = loginByEmail;
+exports.bindByMobile = bindByMobile;
+exports.bindByEmail = bindByEmail;
+exports.setUserAvatarFromWechat = setUserAvatarFromWechat;
+exports.refreshWechatPublicUserInfo = refreshWechatPublicUserInfo;
+exports.loginByWechat = loginByWechat;
+exports.loginWechatNative = loginWechatNative;
+exports.loginWechat = loginWechat;
+exports.loginWechatMp = loginWechatMp;
+exports.syncUserInfoWechatMp = syncUserInfoWechatMp;
+exports.sendCaptchaByMobile = sendCaptchaByMobile;
+exports.sendCaptchaByEmail = sendCaptchaByEmail;
+exports.switchTo = switchTo;
+exports.getWechatMpUserPhoneNumber = getWechatMpUserPhoneNumber;
+exports.logout = logout;
+exports.wakeupParasite = wakeupParasite;
+exports.refreshToken = refreshToken;
+exports.loginWebByMpToken = loginWebByMpToken;
const tslib_1 = require("tslib");
const uuid_1 = require("oak-domain/lib/utils/uuid");
const WechatSDK_1 = tslib_1.__importDefault(require("oak-external-sdk/lib/WechatSDK"));
@@ -380,7 +402,6 @@ createData, user) {
}
}
}
-exports.setUpTokenAndUser = setUpTokenAndUser;
async function setupMobile(mobile, env, context) {
const result2 = await context.select('mobile', {
data: {
@@ -444,7 +465,6 @@ async function loadTokenInfo(tokenValue, context) {
},
}, {});
}
-exports.loadTokenInfo = loadTokenInfo;
async function loginByMobile(params, context) {
const { mobile, captcha, env, disableRegister } = params;
const loginLogic = async (isRoot) => {
@@ -540,26 +560,11 @@ async function loginByMobile(params, context) {
closeRootMode();
return tokenValue;
}
-exports.loginByMobile = loginByMobile;
async function verifyPassword(params, context) {
const { password } = params;
- const systemId = context.getSystemId();
- const [pwdPassport] = await context.select('passport', {
- data: {
- id: 1,
- systemId: 1,
- config: 1,
- type: 1,
- enabled: 1,
- },
- filter: {
- systemId,
- enabled: true,
- type: 'password',
- }
- }, { forUpdate: true });
- // assert(pwdPassport);
- const pwdMode = pwdPassport?.config?.mode ?? 'all';
+ const { system } = context.getApplication();
+ const pwdConfig = system?.config.Password;
+ const pwdMode = pwdConfig?.mode ?? 'all';
let pwdFilter = {};
if (pwdMode === 'all') {
pwdFilter = {
@@ -605,7 +610,6 @@ async function verifyPassword(params, context) {
}
}, {});
}
-exports.verifyPassword = verifyPassword;
async function loginByAccount(params, context) {
const { account, password, env } = params;
let needUpdatePassword = false;
@@ -672,13 +676,15 @@ async function loginByAccount(params, context) {
id: 1,
type: 1,
systemId: 1,
- }
+ },
+ allowPwd: 1,
},
filter: {
passport: {
systemId,
},
applicationId,
+ allowPwd: true,
}
}, {
dontCollect: true,
@@ -769,13 +775,15 @@ async function loginByAccount(params, context) {
id: 1,
type: 1,
systemId: 1,
- }
+ },
+ allowPwd: 1,
},
filter: {
passport: {
systemId,
},
applicationId,
+ allowPwd: true,
}
}, {
dontCollect: true,
@@ -883,29 +891,9 @@ async function loginByAccount(params, context) {
}
};
const closeRootMode = context.openRootMode();
- const application = context.getApplication();
- const [applicationPassport] = await context.select('applicationPassport', {
- data: {
- id: 1,
- passportId: 1,
- passport: {
- id: 1,
- config: 1,
- type: 1,
- },
- applicationId: 1,
- },
- filter: {
- applicationId: application?.id,
- passport: {
- type: 'password',
- },
- }
- }, {
- dontCollect: true,
- });
- // assert(applicationPassport?.passport);
- const pwdMode = applicationPassport?.passport?.config?.mode ?? 'all';
+ const { system } = context.getApplication();
+ const pwdConfig = system?.config.Password;
+ const pwdMode = pwdConfig?.mode ?? 'all';
let pwdFilter = {}, updateData = {};
if (pwdMode === 'all') {
pwdFilter = {
@@ -958,7 +946,6 @@ async function loginByAccount(params, context) {
closeRootMode();
return tokenValue;
}
-exports.loginByAccount = loginByAccount;
async function loginByEmail(params, context) {
const { email, captcha, env, disableRegister } = params;
const loginLogic = async () => {
@@ -1029,7 +1016,6 @@ async function loginByEmail(params, context) {
closeRootMode();
return tokenValue;
}
-exports.loginByEmail = loginByEmail;
async function bindByMobile(params, context) {
const { mobile, captcha, env, } = params;
const userId = context.getCurrentUserId();
@@ -1141,7 +1127,6 @@ async function bindByMobile(params, context) {
await bindLogic();
closeRootMode();
}
-exports.bindByMobile = bindByMobile;
async function bindByEmail(params, context) {
const { email, captcha, env, } = params;
const userId = context.getCurrentUserId();
@@ -1254,7 +1239,6 @@ async function bindByEmail(params, context) {
await bindLogic();
closeRootMode();
}
-exports.bindByEmail = bindByEmail;
async function setupLoginName(name, env, context) {
const result2 = await context.select('loginName', {
data: {
@@ -1495,7 +1479,6 @@ async function setUserAvatarFromWechat(params, context) {
}, {});
}
}
-exports.setUserAvatarFromWechat = setUserAvatarFromWechat;
async function tryRefreshWechatPublicUserInfo(wechatUserId, context) {
const [wechatUser] = await context.select('wechatUser', {
data: {
@@ -1584,7 +1567,6 @@ async function refreshWechatPublicUserInfo({}, context) {
(0, assert_1.assert)(token.entityId);
return await tryRefreshWechatPublicUserInfo(token.entityId, context);
}
-exports.refreshWechatPublicUserInfo = refreshWechatPublicUserInfo;
// 用户在微信端授权登录后,在web端触发该方法
async function loginByWechat(params, context) {
const { wechatLoginId, env } = params;
@@ -1614,7 +1596,6 @@ async function loginByWechat(params, context) {
closeRootMode();
return tokenValue;
}
-exports.loginByWechat = loginByWechat;
async function loginFromWechatEnv(code, env, context, wechatLoginId) {
const application = context.getApplication();
const { type, config, systemId } = application;
@@ -1958,7 +1939,6 @@ async function loginWechatNative({ code, env, }, context) {
closeRootMode();
return tokenValue;
}
-exports.loginWechatNative = loginWechatNative;
/**
* 公众号授权登录
* @param param0
@@ -1989,7 +1969,6 @@ async function loginWechat({ code, env, wechatLoginId, }, context) {
closeRootMode();
return tokenValue;
}
-exports.loginWechat = loginWechat;
/**
* 小程序授权登录
* @param param0
@@ -2003,7 +1982,6 @@ async function loginWechatMp({ code, env, }, context) {
closeRootMode();
return tokenValue;
}
-exports.loginWechatMp = loginWechatMp;
/**
* 同步从wx.getUserProfile拿到的用户信息
* @param param0
@@ -2057,7 +2035,6 @@ async function syncUserInfoWechatMp({ nickname, avatarUrl, encryptedData, iv, si
// 实测发现解密出来的和userInfo完全一致……
await setUserInfoFromWechat(user, { nickname, avatar: avatarUrl }, context);
}
-exports.syncUserInfoWechatMp = syncUserInfoWechatMp;
async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context) {
const { type } = env;
let visitorId = mobile;
@@ -2222,7 +2199,6 @@ async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context)
return '验证码发送失败';
}
}
-exports.sendCaptchaByMobile = sendCaptchaByMobile;
async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
const { type } = env;
let visitorId = email;
@@ -2370,7 +2346,6 @@ async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
return '验证码发送失败';
}
}
-exports.sendCaptchaByEmail = sendCaptchaByEmail;
async function switchTo({ userId }, context) {
const reallyRoot = context.isReallyRoot();
if (!reallyRoot) {
@@ -2392,7 +2367,6 @@ async function switchTo({ userId }, context) {
},
}, {});
}
-exports.switchTo = switchTo;
async function getWechatMpUserPhoneNumber({ code, env }, context) {
const application = context.getApplication();
const { type, config, systemId } = application;
@@ -2408,7 +2382,6 @@ async function getWechatMpUserPhoneNumber({ code, env }, context) {
closeRootMode();
return reuslt;
}
-exports.getWechatMpUserPhoneNumber = getWechatMpUserPhoneNumber;
async function logout(params, context) {
const { tokenValue } = params;
if (tokenValue) {
@@ -2431,7 +2404,6 @@ async function logout(params, context) {
closeRootMode();
}
}
-exports.logout = logout;
/**
* 创建一个当前parasite上的token
* @param params
@@ -2498,7 +2470,6 @@ async function wakeupParasite(params, context) {
closeRootMode();
return tokenValue;
}
-exports.wakeupParasite = wakeupParasite;
/**
* todo 检查登录环境一致性,同一个token不能跨越不同设备
* @param env1
@@ -2571,8 +2542,8 @@ async function refreshToken(params, context) {
// 只有server模式去刷新token
// 'development' | 'production' | 'staging'
const intervals = {
- development: 7200 * 1000,
- staging: 600 * 1000,
+ development: 7200 * 1000, // 2小时
+ staging: 600 * 1000, // 十分钟
production: 600 * 1000, // 十分钟
};
let applicationId = token.applicationId;
@@ -2645,7 +2616,6 @@ async function refreshToken(params, context) {
closeRootMode();
return tokenValue;
}
-exports.refreshToken = refreshToken;
/**
* 使用微信小程序中的token登录web
* @param tokenValue
@@ -2713,4 +2683,3 @@ async function loginWebByMpToken(params, context) {
closeRootMode();
return tokenValue;
}
-exports.loginWebByMpToken = loginWebByMpToken;
diff --git a/lib/types/Config.d.ts b/lib/types/Config.d.ts
index 36e54fe4a..9a713bf07 100644
--- a/lib/types/Config.d.ts
+++ b/lib/types/Config.d.ts
@@ -151,6 +151,14 @@ export type EmailConfig = {
name?: string;
secure?: boolean;
};
+export type PasswordConfig = {
+ mode?: 'all' | 'plain' | 'sha1';
+ min?: number;
+ max?: number;
+ verify?: boolean;
+ regexs?: string[];
+ tip?: string;
+};
export type QrCodeType = 'wechatMpDomainUrl' | 'wechatMpWxaCode' | 'wechatPublic' | 'wechatPublicForMp' | 'webForWechatPublic';
export type Config = {
Account?: {
@@ -202,6 +210,7 @@ export type Config = {
level?: 'weak' | 'medium' | 'strong';
passwordVerifyGap?: number;
};
+ Password?: PasswordConfig;
};
export type AccountOrigin = 'ali' | 'tencent' | 'qiniu' | 'amap' | 'ctyun' | 'local' | 's3';
export type CosOrigin = 'qiniu' | 'wechat' | 'ctyun' | 'aliyun' | 'tencent' | 'local' | 'unknown' | 's3';
diff --git a/src/aspects/token.ts b/src/aspects/token.ts
index 40c7a694b..8014e6804 100644
--- a/src/aspects/token.ts
+++ b/src/aspects/token.ts
@@ -40,7 +40,7 @@ import { sendSms } from '../utils/sms';
import { mergeUser } from './user';
import { cloneDeep, pick } from 'oak-domain/lib/utils/lodash';
import { BRC } from '../types/RuntimeCxt';
-import { PwdConfig, SmsConfig } from '../entities/Passport';
+import { SmsConfig } from '../entities/Passport';
import { sendEmail } from '../utils/email';
import { EmailConfig } from '../oak-app-domain/Passport/Schema';
import { isEmail, isMobile } from 'oak-domain/lib/utils/validator';
@@ -730,23 +730,9 @@ export async function verifyPassword(
context: BRC
) {
const { password } = params;
- const systemId = context.getSystemId();
- const [pwdPassport] = await context.select('passport', {
- data: {
- id: 1,
- systemId: 1,
- config: 1,
- type: 1,
- enabled: 1,
- },
- filter: {
- systemId,
- enabled: true,
- type: 'password',
- }
- }, { forUpdate: true });
- // assert(pwdPassport);
- const pwdMode = (pwdPassport?.config as PwdConfig)?.mode ?? 'all';
+ const { system } = context.getApplication()!;
+ const pwdConfig = system?.config.Password;
+ const pwdMode = pwdConfig?.mode ?? 'all';
let pwdFilter = {};
if (pwdMode === 'all') {
pwdFilter = {
@@ -881,13 +867,15 @@ export async function loginByAccount(
id: 1,
type: 1,
systemId: 1,
- }
+ },
+ allowPwd: 1,
},
filter: {
passport: {
systemId,
},
applicationId,
+ allowPwd: true,
}
},
{
@@ -991,13 +979,15 @@ export async function loginByAccount(
id: 1,
type: 1,
systemId: 1,
- }
+ },
+ allowPwd: 1,
},
filter: {
passport: {
systemId,
},
applicationId,
+ allowPwd: true,
}
},
{
@@ -1119,32 +1109,9 @@ export async function loginByAccount(
}
};
const closeRootMode = context.openRootMode();
- const application = context.getApplication();
- const [applicationPassport] = await context.select('applicationPassport',
- {
- data: {
- id: 1,
- passportId: 1,
- passport: {
- id: 1,
- config: 1,
- type: 1,
- },
- applicationId: 1,
- },
- filter: {
- applicationId: application?.id!,
- passport: {
- type: 'password',
- },
- }
- },
- {
- dontCollect: true,
- }
- );
- // assert(applicationPassport?.passport);
- const pwdMode = (applicationPassport?.passport?.config as PwdConfig)?.mode ?? 'all';
+ const { system } = context.getApplication()!;
+ const pwdConfig = system?.config.Password;
+ const pwdMode = pwdConfig?.mode ?? 'all';
let pwdFilter = {}, updateData = {};
if (pwdMode === 'all') {
pwdFilter = {
@@ -3324,7 +3291,7 @@ export async function refreshToken(
if (!token) {
throw new OakUnloggedInException("Token令牌已失效,请重新登录");
}
-
+
const now = Date.now();
if (!checkTokenEnvConsistency(env, token.env as WebEnv)) {
console.log('####### refreshToken 环境改变 start #######\n');
diff --git a/src/components/changePassword/byMobile/index.ts b/src/components/changePassword/byMobile/index.ts
index 12b5c323f..e86791f97 100644
--- a/src/components/changePassword/byMobile/index.ts
+++ b/src/components/changePassword/byMobile/index.ts
@@ -63,9 +63,8 @@ export default OakComponent({
lifetimes: {
async ready() {
const lastSendAt = await this.load(SEND_KEY);
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig: PwdConfig = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/src/components/changePassword/byPassword/index.ts b/src/components/changePassword/byPassword/index.ts
index 3afe1f8a9..eace07d57 100644
--- a/src/components/changePassword/byPassword/index.ts
+++ b/src/components/changePassword/byPassword/index.ts
@@ -26,9 +26,8 @@ export default OakComponent({
},
lifetimes: {
async ready() {
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig: PwdConfig = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/src/components/config/upsert/password/index.tsx b/src/components/config/upsert/password/index.tsx
new file mode 100644
index 000000000..f559c7107
--- /dev/null
+++ b/src/components/config/upsert/password/index.tsx
@@ -0,0 +1,136 @@
+import React, { useEffect, useState } from 'react';
+import {
+ Tabs,
+ Row,
+ Col,
+ Card,
+ Divider,
+ Input,
+ Form,
+ Space,
+ Select,
+ Radio,
+ InputNumber,
+ Switch,
+} from 'antd';
+import Styles from './web.module.less';
+import { Config } from '../../../../types/Config';
+import EditorRegexs from '../../../passport/password/editorRegexs';
+
+export default function Security(props: {
+ password: Required['Password'];
+ setValue: (path: string, value: any) => void;
+ setValues: (value: Record) => void;
+}) {
+ const { password, setValue, setValues } = props;
+ const { mode, min, max, verify, regexs, tip } = password || {};
+ const [newTip, setNewTip] = useState('');
+
+ useEffect(() => {
+ const { password } = props;
+ if (!password.mode) {
+ setValues({
+ mode: 'all',
+ min: 8,
+ max: 24,
+ });
+ }
+ }, [password]);
+
+ useEffect(() => {
+ if (tip && !newTip) {
+ setNewTip(tip)
+ }
+ }, [tip]);
+
+ return (
+
+
+
+ 密码设置
+
+
+ {
+ const { value } = target;
+ setValue('mode', value);
+ }}
+ value={mode}
+ >
+ 明文与SHA1加密
+ 仅明文
+ 仅SHA1加密
+
+
+
+
+ {
+ setValue('min', value);
+ }} />
+ ~
+ {
+ setValue('max', value);
+ }} />
+
+
+
+
+ {
+ setValue('verigy', checked)
+ }}
+ />
+
+
+ <>
+ {!!verify ? (
+ <>
+ {
+ setValue('regexs', regexs);
+ }} />
+ >
+ ) : (
+ 暂未启用正则校验,无需设置
+ )}
+ >
+
+
+ {
+ setNewTip(e.target.value);
+ }}
+ onBlur={() => {
+ if (newTip && newTip !== tip) {
+ setValue('tip', newTip);
+ }
+ }}
+ />
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/config/upsert/password/web.module.less b/src/components/config/upsert/password/web.module.less
new file mode 100644
index 000000000..7fa576eed
--- /dev/null
+++ b/src/components/config/upsert/password/web.module.less
@@ -0,0 +1,16 @@
+
+.label {
+ color: var(--oak-text-color-primary);
+ font-size: 28px;
+ line-height: 36px;
+}
+
+.tips {
+ color: var(--oak-text-color-placeholder);
+ font-size: 12px;
+}
+
+.title {
+ margin-bottom: 0px;
+ margin-top:36px;
+}
\ No newline at end of file
diff --git a/src/components/config/upsert/web.pc.tsx b/src/components/config/upsert/web.pc.tsx
index b42eec2b7..eb3e2cd63 100644
--- a/src/components/config/upsert/web.pc.tsx
+++ b/src/components/config/upsert/web.pc.tsx
@@ -9,6 +9,7 @@ import Sms from './sms/index';
import Email from './email/index';
import Basic from './basic/index';
import Security from './security/index';
+import Password from './password/index';
import { Config } from '../../../types/Config';
import { EntityDict } from '../../../oak-app-domain';
@@ -47,6 +48,7 @@ export default function Render(
App: app,
Emails: emails,
Security: security,
+ Password: password,
} = currentConfig || {};
return (
<>
@@ -228,6 +230,23 @@ export default function Render(
/>
),
},
+ {
+ key: '密码设置',
+ label: '密码设置',
+ children: (
+
+ setValue(`Password.${path}`, value)
+ }
+ setValues={(value) => {
+ setValues({
+ Password: value
+ });
+ }}
+ />
+ ),
+ },
]}
>
diff --git a/src/components/user/password/update/index.ts b/src/components/user/password/update/index.ts
index cb263fa81..9f36ed797 100644
--- a/src/components/user/password/update/index.ts
+++ b/src/components/user/password/update/index.ts
@@ -38,9 +38,8 @@ export default OakComponent({
},
lifetimes: {
async ready() {
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig: PwdConfig = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/src/components/user/password/verify/index.ts b/src/components/user/password/verify/index.ts
index 0fee05c23..826700709 100644
--- a/src/components/user/password/verify/index.ts
+++ b/src/components/user/password/verify/index.ts
@@ -14,9 +14,8 @@ export default OakComponent({
lifetimes: {
async ready() {
this.features.token.getToken();
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig: PwdConfig = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
this.setState({
mode,
diff --git a/src/components/userRelation/upsert/onUser/index.ts b/src/components/userRelation/upsert/onUser/index.ts
index 711d0e50c..011c62689 100644
--- a/src/components/userRelation/upsert/onUser/index.ts
+++ b/src/components/userRelation/upsert/onUser/index.ts
@@ -90,9 +90,8 @@ export default OakComponent({
},
lifetimes: {
async ready() {
- const application = this.features.application.getApplication();
- const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
- const passwordConfig: PwdConfig = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type === 'password')?.passport.config;
+ const system = this.features.application.getApplication().system;
+ const passwordConfig = system?.config.Password;
const mode = passwordConfig?.mode ?? 'all';
const pwdMin = passwordConfig?.min ?? 8;
const pwdMax = passwordConfig?.max ?? 24;
diff --git a/src/types/Config.ts b/src/types/Config.ts
index 75eea59dc..cdc0a865a 100644
--- a/src/types/Config.ts
+++ b/src/types/Config.ts
@@ -81,7 +81,7 @@ export type LocalCosConfig = {
};
// S3/Minio 的区域类型(可以根据实际需要扩展)
-export type S3Zone =
+export type S3Zone =
| 'us-east-1'
| 'us-west-1'
| 'us-west-2'
@@ -185,6 +185,15 @@ export type EmailConfig = {
secure?: boolean; //是否ssl
};
+export type PasswordConfig = {
+ mode?: 'all' | 'plain' | 'sha1' //密码存储模式,默认为all
+ min?: number; //位数最小值,默认为8
+ max?: number; //位数最大值,默认为24
+ verify?: boolean; //开启正则校验,默认不开启
+ regexs?: string[];
+ tip?: string; //登录提示语
+};
+
export type QrCodeType = 'wechatMpDomainUrl' | 'wechatMpWxaCode' | 'wechatPublic' | 'wechatPublicForMp' | 'webForWechatPublic';
export type Config = {
@@ -236,7 +245,8 @@ export type Config = {
type?: 'password', // 采用密码作为第一安全元素
level?: 'weak' | 'medium' | 'strong'; // 强度
passwordVerifyGap?: number; // 在密码验证后的多长时间内认为是安全的,可以做敏感动作
- }
+ };
+ Password?: PasswordConfig;
};
export type AccountOrigin = 'ali' | 'tencent' | 'qiniu' | 'amap' | 'ctyun' | 'local' | 's3';