Merge branch 'dev' of gitea.51mars.com:Oak-Team/oak-general-business into dev
This commit is contained in:
commit
341027ca82
|
|
@ -11,6 +11,7 @@ import { mergeUser } from './user';
|
|||
import { cloneDeep } from 'oak-domain/lib/utils/lodash';
|
||||
import { sendEmail } from '../utils/email';
|
||||
import { isEmail, isMobile } from 'oak-domain/lib/utils/validator';
|
||||
import { getAndCheckPassportByEmail } from '../utils/passport';
|
||||
async function makeDistinguishException(userId, context, message) {
|
||||
const [user] = await context.select('user', {
|
||||
data: {
|
||||
|
|
@ -468,6 +469,16 @@ export async function loginByMobile(params, context) {
|
|||
if (captchaRow.expired) {
|
||||
throw new OakUserException('验证码已经过期');
|
||||
}
|
||||
await context.operate('captcha', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captchaRow.id
|
||||
}
|
||||
}, {});
|
||||
// 到这里说明验证码已经通过
|
||||
return await setupMobile(mobile, env, context);
|
||||
}
|
||||
|
|
@ -560,49 +571,7 @@ export async function loginByAccount(params, context) {
|
|||
assert(account);
|
||||
const accountType = isEmail(account) ? 'email' : (isMobile(account) ? 'mobile' : 'loginName');
|
||||
if (accountType === 'email') {
|
||||
// const application = context.getApplication();
|
||||
// const { system } = application!;
|
||||
// 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: 'email'
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// dontCollect: true,
|
||||
// }
|
||||
// );
|
||||
// assert(applicationPassport?.passport);
|
||||
// const config = applicationPassport.passport.config as EmailConfig;
|
||||
// const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
// assert(emailConfig);
|
||||
// const emailSuffixes = config.emailSuffixes;
|
||||
// // 检查邮箱后缀是否满足配置
|
||||
// if (emailSuffixes?.length! > 0) {
|
||||
// let isValid = false;
|
||||
// for (const suffix of emailSuffixes!) {
|
||||
// if (account.endsWith(suffix)) {
|
||||
// isValid = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!isValid) {
|
||||
// throw new OakUserException('error::user.emailSuffixIsInvalid');
|
||||
// }
|
||||
// }
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, account);
|
||||
const existEmail = await context.select('email', {
|
||||
data: {
|
||||
id: 1,
|
||||
|
|
@ -980,46 +949,7 @@ export async function loginByEmail(params, context) {
|
|||
}
|
||||
};
|
||||
const closeRootMode = context.openRootMode();
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new OakUserException('邮箱后缀不符合要求');
|
||||
}
|
||||
}
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, email);
|
||||
if (disableRegister) {
|
||||
const [existEmail] = await context.select('email', {
|
||||
data: {
|
||||
|
|
@ -1073,6 +1003,16 @@ export async function bindByMobile(params, context) {
|
|||
throw new OakUserException('验证码已经过期');
|
||||
}
|
||||
// 到这里说明验证码已经通过
|
||||
await context.operate('captcha', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captchaRow.id
|
||||
}
|
||||
}, {});
|
||||
// 检查当前user是否已绑定mobile
|
||||
const [boundMobile] = await context.select('mobile', {
|
||||
data: {
|
||||
|
|
@ -1233,46 +1173,7 @@ export async function bindByEmail(params, context) {
|
|||
}
|
||||
};
|
||||
const closeRootMode = context.openRootMode();
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new OakUserException('邮箱后缀不符合要求');
|
||||
}
|
||||
}
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, email);
|
||||
const [otherUserEmail] = await context.select('email', {
|
||||
data: {
|
||||
id: 1,
|
||||
|
|
@ -2054,6 +1955,7 @@ export async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, c
|
|||
const [count1, count2] = await Promise.all([
|
||||
context.count('captcha', {
|
||||
filter: {
|
||||
origin: 'mobile',
|
||||
visitorId,
|
||||
$$createAt$$: {
|
||||
$gt: now - 3600 * 1000,
|
||||
|
|
@ -2105,10 +2007,11 @@ export async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, c
|
|||
code = mobile.substring(11 - digit);
|
||||
}
|
||||
else {
|
||||
code = Math.floor(Math.random() * Math.pow(10, digit)).toString();
|
||||
while (code.length < digit) {
|
||||
code += '0';
|
||||
}
|
||||
// code = Math.floor(Math.random() * Math.pow(10, digit)).toString();
|
||||
// while (code.length < digit) {
|
||||
// code += '0';
|
||||
// }
|
||||
code = Array.from({ length: digit }, () => Math.floor(Math.random() * 10)).join('');
|
||||
}
|
||||
const id = await generateNewIdAsync();
|
||||
await context.operate('captcha', {
|
||||
|
|
@ -2137,6 +2040,17 @@ export async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, c
|
|||
closeRootMode();
|
||||
throw new OakUserException('您的操作太迅捷啦,请稍候再点吧');
|
||||
}
|
||||
await context.operate('captcha', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captcha.id
|
||||
}
|
||||
}, {});
|
||||
code = await getCode();
|
||||
}
|
||||
else {
|
||||
code = await getCode();
|
||||
|
|
@ -2168,49 +2082,10 @@ export async function sendCaptchaByEmail({ email, env, type: captchaType, }, con
|
|||
if (type === 'web' || type === 'native') {
|
||||
visitorId = env.visitorId;
|
||||
}
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, email);
|
||||
const duration = config.codeDuration || 5;
|
||||
const digit = config.digit || 4;
|
||||
const mockSend = config.mockSend;
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new OakUserException('邮箱后缀不符合要求');
|
||||
}
|
||||
}
|
||||
let emailOptions = {
|
||||
// host: emailConfig.host,
|
||||
// port: emailConfig.port,
|
||||
|
|
@ -2229,6 +2104,7 @@ export async function sendCaptchaByEmail({ email, env, type: captchaType, }, con
|
|||
const [count1, count2] = await Promise.all([
|
||||
context.count('captcha', {
|
||||
filter: {
|
||||
origin: 'email',
|
||||
visitorId,
|
||||
$$createAt$$: {
|
||||
$gt: now - 3600 * 1000,
|
||||
|
|
@ -2276,10 +2152,11 @@ export async function sendCaptchaByEmail({ email, env, type: captchaType, }, con
|
|||
});
|
||||
const getCode = async () => {
|
||||
let code;
|
||||
code = Math.floor(Math.random() * Math.random() * Math.pow(10, digit)).toString();
|
||||
while (code.length < digit) {
|
||||
code += '0';
|
||||
}
|
||||
// code = Math.floor(Math.random() * Math.random() * Math.pow(10, digit)).toString();
|
||||
// while (code.length < digit) {
|
||||
// code += '0';
|
||||
// }
|
||||
code = Array.from({ length: digit }, () => Math.floor(Math.random() * 10)).join('');
|
||||
const id = await generateNewIdAsync();
|
||||
await context.operate('captcha', {
|
||||
id: await generateNewIdAsync(),
|
||||
|
|
@ -2307,6 +2184,17 @@ export async function sendCaptchaByEmail({ email, env, type: captchaType, }, con
|
|||
closeRootMode();
|
||||
throw new OakUserException('您的操作太迅捷啦,请稍候再点吧');
|
||||
}
|
||||
await context.operate('captcha', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captcha.id
|
||||
}
|
||||
}, {});
|
||||
code = await getCode();
|
||||
}
|
||||
else {
|
||||
code = await getCode();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,24 @@ export default function Web(props) {
|
|||
</Form>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
网站-微信支付
|
||||
</Divider>
|
||||
<Form colon={true} labelAlign="left" layout="vertical" style={{ marginTop: 10 }}>
|
||||
<Form.Item label="appId">
|
||||
<>
|
||||
<Input placeholder="请输入appId" type="text" value={config?.wechatPay?.appId} onChange={(e) => setValue(`wechatPay.appId`, e.target.value)}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="appSecret">
|
||||
<>
|
||||
<Input placeholder="请输入appSecret" type="text" value={config?.wechatPay?.appSecret} onChange={(e) => setValue(`wechatPay.appSecret`, e.target.value)}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
location
|
||||
|
|
@ -68,61 +86,5 @@ export default function Web(props) {
|
|||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
{/* <Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
网站-授权方式
|
||||
</Divider>
|
||||
<Form
|
||||
colon={true}
|
||||
labelAlign="left"
|
||||
layout="vertical"
|
||||
style={{ marginTop: 10 }}
|
||||
>
|
||||
<Form.Item label="passport"
|
||||
//name="passport"
|
||||
>
|
||||
<>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
placeholder="请选择授权方式"
|
||||
value={config?.passport as Passport[]}
|
||||
onChange={(value: Passport[]) => {
|
||||
if (value.includes('wechat') && value.includes('wechatPublic')) {
|
||||
message.warning('微信网站和微信公众号中,只能选择一个')
|
||||
return;
|
||||
}
|
||||
setValue(`passport`, value);
|
||||
}}
|
||||
options={
|
||||
[
|
||||
{
|
||||
label: '邮箱',
|
||||
value: 'email',
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
value: 'mobile',
|
||||
},
|
||||
{
|
||||
label: '微信网站',
|
||||
value: 'wechat',
|
||||
},
|
||||
{
|
||||
label: '微信公众号',
|
||||
value: 'wechatPublic',
|
||||
},
|
||||
] as Array<{
|
||||
label: string;
|
||||
value: Passport;
|
||||
}>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col> */}
|
||||
</Space>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ export default function WechatPublic(props) {
|
|||
const [open, setModal] = useState(false);
|
||||
const [messageType, setMessageType] = useState('');
|
||||
const { config, setValue, cleanKey, removeItem, isService = true } = props;
|
||||
const templateMsgs = config?.templateMsgs || {};
|
||||
return (<Space direction="vertical" size="middle" style={{ display: 'flex' }}>
|
||||
<Row>
|
||||
<Card className={Styles.tips}>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Style } from '../../../../types/Style';
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../../oak-app-domain").EntityDict, keyof import("../../../../oak-app-domain").EntityDict, false, {
|
||||
style: Style;
|
||||
entity: "application" | "system" | "platform";
|
||||
entity: "system" | "platform" | "application";
|
||||
entityId: string;
|
||||
name: string;
|
||||
}>) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
|||
loadingIcon?: import("react").ReactNode;
|
||||
disabled?: boolean | undefined;
|
||||
onClick?: ((event: import("react").MouseEvent<HTMLButtonElement, MouseEvent>) => unknown) | undefined;
|
||||
type?: "button" | "submit" | "reset" | undefined;
|
||||
type?: "button" | "reset" | "submit" | undefined;
|
||||
shape?: "default" | "rounded" | "rectangular" | undefined;
|
||||
children?: import("react").ReactNode;
|
||||
} & Pick<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement>, "id" | "onMouseDown" | "onMouseUp" | "onTouchEnd" | "onTouchStart"> & {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EntityDict } from '../../../oak-app-domain';
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
type: "login" | "bind";
|
||||
type: "bind" | "login";
|
||||
url: string;
|
||||
size: undefined;
|
||||
}>) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ export type WebConfig = {
|
|||
domain?: string;
|
||||
enable?: boolean;
|
||||
};
|
||||
wechatPay?: {
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http:' | 'https:';
|
||||
|
|
@ -36,14 +40,12 @@ export type WebConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
type: 'wechatPublic';
|
||||
isService: boolean;
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
originalId?: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
server?: {
|
||||
url?: string;
|
||||
token: string;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ export type WebConfig = {
|
|||
domain?: string;
|
||||
enable?: boolean;
|
||||
};
|
||||
wechatPay?: {
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: "http:" | "https:";
|
||||
|
|
@ -36,14 +40,12 @@ export type WebConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
type: "wechatPublic";
|
||||
isService: boolean;
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
originalId?: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
server?: {
|
||||
url?: string;
|
||||
token: string;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export declare function createToDo<ED extends EntityDict & BaseEntityDict, T ext
|
|||
redirectTo: EntityDict['toDo']['OpSchema']['redirectTo'];
|
||||
entity: any;
|
||||
entityId: string;
|
||||
}, userIds?: string[]): Promise<0 | 1>;
|
||||
}, userIds?: string[]): Promise<1 | 0>;
|
||||
/**
|
||||
* 完成todo例程,当在entity对象上进行action操作时(操作条件是filter),将对应的todo完成
|
||||
* 必须在entity的action的后trigger中调用
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ export type QiniuLiveConfig = {
|
|||
liveHost: string;
|
||||
hub: string;
|
||||
publishDomain: string;
|
||||
playDomainType: 'rtmp' | 'hls' | 'flv';
|
||||
playDomainType?: 'rtmp' | 'hls' | 'flv';
|
||||
playDomain: string;
|
||||
playBackDomain: string;
|
||||
publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk';
|
||||
publishSecurity?: 'none' | 'static' | 'expiry' | 'expiry_sk';
|
||||
publishKey: string;
|
||||
playKey: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import { EntityDict } from "../oak-app-domain";
|
||||
import { BRC } from "../types/RuntimeCxt";
|
||||
import { EmailConfig } from '../oak-app-domain/Passport/Schema';
|
||||
export declare function getAndCheckPassportByEmail<ED extends EntityDict>(context: BRC<ED>, email: string): Promise<{
|
||||
emailConfig: import("../types/Config").EmailConfig;
|
||||
config: EmailConfig;
|
||||
}>;
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { OakUserException } from 'oak-domain/lib/types';
|
||||
export async function getAndCheckPassportByEmail(context, email) {
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email',
|
||||
},
|
||||
},
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new OakUserException('error::user.emailSuffixIsInvalid');
|
||||
}
|
||||
}
|
||||
return {
|
||||
emailConfig,
|
||||
config
|
||||
};
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ const user_1 = require("./user");
|
|||
const lodash_1 = require("oak-domain/lib/utils/lodash");
|
||||
const email_1 = require("../utils/email");
|
||||
const validator_1 = require("oak-domain/lib/utils/validator");
|
||||
const passport_1 = require("../utils/passport");
|
||||
async function makeDistinguishException(userId, context, message) {
|
||||
const [user] = await context.select('user', {
|
||||
data: {
|
||||
|
|
@ -472,6 +473,16 @@ async function loginByMobile(params, context) {
|
|||
if (captchaRow.expired) {
|
||||
throw new types_1.OakUserException('验证码已经过期');
|
||||
}
|
||||
await context.operate('captcha', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captchaRow.id
|
||||
}
|
||||
}, {});
|
||||
// 到这里说明验证码已经通过
|
||||
return await setupMobile(mobile, env, context);
|
||||
}
|
||||
|
|
@ -566,49 +577,7 @@ async function loginByAccount(params, context) {
|
|||
(0, assert_1.assert)(account);
|
||||
const accountType = (0, validator_1.isEmail)(account) ? 'email' : ((0, validator_1.isMobile)(account) ? 'mobile' : 'loginName');
|
||||
if (accountType === 'email') {
|
||||
// const application = context.getApplication();
|
||||
// const { system } = application!;
|
||||
// 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: 'email'
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// dontCollect: true,
|
||||
// }
|
||||
// );
|
||||
// assert(applicationPassport?.passport);
|
||||
// const config = applicationPassport.passport.config as EmailConfig;
|
||||
// const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
// assert(emailConfig);
|
||||
// const emailSuffixes = config.emailSuffixes;
|
||||
// // 检查邮箱后缀是否满足配置
|
||||
// if (emailSuffixes?.length! > 0) {
|
||||
// let isValid = false;
|
||||
// for (const suffix of emailSuffixes!) {
|
||||
// if (account.endsWith(suffix)) {
|
||||
// isValid = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!isValid) {
|
||||
// throw new OakUserException('error::user.emailSuffixIsInvalid');
|
||||
// }
|
||||
// }
|
||||
const { config, emailConfig } = await (0, passport_1.getAndCheckPassportByEmail)(context, account);
|
||||
const existEmail = await context.select('email', {
|
||||
data: {
|
||||
id: 1,
|
||||
|
|
@ -987,46 +956,7 @@ async function loginByEmail(params, context) {
|
|||
}
|
||||
};
|
||||
const closeRootMode = context.openRootMode();
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
(0, assert_1.assert)(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
(0, assert_1.assert)(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new types_1.OakUserException('邮箱后缀不符合要求');
|
||||
}
|
||||
}
|
||||
const { config, emailConfig } = await (0, passport_1.getAndCheckPassportByEmail)(context, email);
|
||||
if (disableRegister) {
|
||||
const [existEmail] = await context.select('email', {
|
||||
data: {
|
||||
|
|
@ -1081,6 +1011,16 @@ async function bindByMobile(params, context) {
|
|||
throw new types_1.OakUserException('验证码已经过期');
|
||||
}
|
||||
// 到这里说明验证码已经通过
|
||||
await context.operate('captcha', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captchaRow.id
|
||||
}
|
||||
}, {});
|
||||
// 检查当前user是否已绑定mobile
|
||||
const [boundMobile] = await context.select('mobile', {
|
||||
data: {
|
||||
|
|
@ -1242,46 +1182,7 @@ async function bindByEmail(params, context) {
|
|||
}
|
||||
};
|
||||
const closeRootMode = context.openRootMode();
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
(0, assert_1.assert)(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
(0, assert_1.assert)(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new types_1.OakUserException('邮箱后缀不符合要求');
|
||||
}
|
||||
}
|
||||
const { config, emailConfig } = await (0, passport_1.getAndCheckPassportByEmail)(context, email);
|
||||
const [otherUserEmail] = await context.select('email', {
|
||||
data: {
|
||||
id: 1,
|
||||
|
|
@ -2070,6 +1971,7 @@ async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context)
|
|||
const [count1, count2] = await Promise.all([
|
||||
context.count('captcha', {
|
||||
filter: {
|
||||
origin: 'mobile',
|
||||
visitorId,
|
||||
$$createAt$$: {
|
||||
$gt: now - 3600 * 1000,
|
||||
|
|
@ -2121,10 +2023,11 @@ async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context)
|
|||
code = mobile.substring(11 - digit);
|
||||
}
|
||||
else {
|
||||
code = Math.floor(Math.random() * Math.pow(10, digit)).toString();
|
||||
while (code.length < digit) {
|
||||
code += '0';
|
||||
}
|
||||
// code = Math.floor(Math.random() * Math.pow(10, digit)).toString();
|
||||
// while (code.length < digit) {
|
||||
// code += '0';
|
||||
// }
|
||||
code = Array.from({ length: digit }, () => Math.floor(Math.random() * 10)).join('');
|
||||
}
|
||||
const id = await (0, uuid_1.generateNewIdAsync)();
|
||||
await context.operate('captcha', {
|
||||
|
|
@ -2153,6 +2056,17 @@ async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context)
|
|||
closeRootMode();
|
||||
throw new types_1.OakUserException('您的操作太迅捷啦,请稍候再点吧');
|
||||
}
|
||||
await context.operate('captcha', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captcha.id
|
||||
}
|
||||
}, {});
|
||||
code = await getCode();
|
||||
}
|
||||
else {
|
||||
code = await getCode();
|
||||
|
|
@ -2185,49 +2099,10 @@ async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
|
|||
if (type === 'web' || type === 'native') {
|
||||
visitorId = env.visitorId;
|
||||
}
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
(0, assert_1.assert)(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
(0, assert_1.assert)(emailConfig);
|
||||
const { config, emailConfig } = await (0, passport_1.getAndCheckPassportByEmail)(context, email);
|
||||
const duration = config.codeDuration || 5;
|
||||
const digit = config.digit || 4;
|
||||
const mockSend = config.mockSend;
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new types_1.OakUserException('邮箱后缀不符合要求');
|
||||
}
|
||||
}
|
||||
let emailOptions = {
|
||||
// host: emailConfig.host,
|
||||
// port: emailConfig.port,
|
||||
|
|
@ -2246,6 +2121,7 @@ async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
|
|||
const [count1, count2] = await Promise.all([
|
||||
context.count('captcha', {
|
||||
filter: {
|
||||
origin: 'email',
|
||||
visitorId,
|
||||
$$createAt$$: {
|
||||
$gt: now - 3600 * 1000,
|
||||
|
|
@ -2293,10 +2169,11 @@ async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
|
|||
});
|
||||
const getCode = async () => {
|
||||
let code;
|
||||
code = Math.floor(Math.random() * Math.random() * Math.pow(10, digit)).toString();
|
||||
while (code.length < digit) {
|
||||
code += '0';
|
||||
}
|
||||
// code = Math.floor(Math.random() * Math.random() * Math.pow(10, digit)).toString();
|
||||
// while (code.length < digit) {
|
||||
// code += '0';
|
||||
// }
|
||||
code = Array.from({ length: digit }, () => Math.floor(Math.random() * 10)).join('');
|
||||
const id = await (0, uuid_1.generateNewIdAsync)();
|
||||
await context.operate('captcha', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
|
|
@ -2324,6 +2201,17 @@ async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
|
|||
closeRootMode();
|
||||
throw new types_1.OakUserException('您的操作太迅捷啦,请稍候再点吧');
|
||||
}
|
||||
await context.operate('captcha', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captcha.id
|
||||
}
|
||||
}, {});
|
||||
code = await getCode();
|
||||
}
|
||||
else {
|
||||
code = await getCode();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ export type WebConfig = {
|
|||
domain?: string;
|
||||
enable?: boolean;
|
||||
};
|
||||
wechatPay?: {
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http:' | 'https:';
|
||||
|
|
@ -36,14 +40,12 @@ export type WebConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
type: 'wechatPublic';
|
||||
isService: boolean;
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
originalId?: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
server?: {
|
||||
url?: string;
|
||||
token: string;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ export type WebConfig = {
|
|||
domain?: string;
|
||||
enable?: boolean;
|
||||
};
|
||||
wechatPay?: {
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: "http:" | "https:";
|
||||
|
|
@ -36,14 +40,12 @@ export type WebConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
type: "wechatPublic";
|
||||
isService: boolean;
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
originalId?: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
server?: {
|
||||
url?: string;
|
||||
token: string;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ export type QiniuLiveConfig = {
|
|||
liveHost: string;
|
||||
hub: string;
|
||||
publishDomain: string;
|
||||
playDomainType: 'rtmp' | 'hls' | 'flv';
|
||||
playDomainType?: 'rtmp' | 'hls' | 'flv';
|
||||
playDomain: string;
|
||||
playBackDomain: string;
|
||||
publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk';
|
||||
publishSecurity?: 'none' | 'static' | 'expiry' | 'expiry_sk';
|
||||
publishKey: string;
|
||||
playKey: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import { EntityDict } from "../oak-app-domain";
|
||||
import { BRC } from "../types/RuntimeCxt";
|
||||
import { EmailConfig } from '../oak-app-domain/Passport/Schema';
|
||||
export declare function getAndCheckPassportByEmail<ED extends EntityDict>(context: BRC<ED>, email: string): Promise<{
|
||||
emailConfig: import("../types/Config").EmailConfig;
|
||||
config: EmailConfig;
|
||||
}>;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getAndCheckPassportByEmail = void 0;
|
||||
const assert_1 = require("oak-domain/lib/utils/assert");
|
||||
const types_1 = require("oak-domain/lib/types");
|
||||
async function getAndCheckPassportByEmail(context, email) {
|
||||
const application = context.getApplication();
|
||||
const { system } = application;
|
||||
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: 'email',
|
||||
},
|
||||
},
|
||||
}, {
|
||||
dontCollect: true,
|
||||
});
|
||||
(0, assert_1.assert)(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
(0, assert_1.assert)(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
throw new types_1.OakUserException('error::user.emailSuffixIsInvalid');
|
||||
}
|
||||
}
|
||||
return {
|
||||
emailConfig,
|
||||
config
|
||||
};
|
||||
}
|
||||
exports.getAndCheckPassportByEmail = getAndCheckPassportByEmail;
|
||||
|
|
@ -44,6 +44,7 @@ import { sendEmail } from '../utils/email';
|
|||
import { EmailConfig } from '../oak-app-domain/Passport/Schema';
|
||||
import { isEmail, isMobile } from 'oak-domain/lib/utils/validator';
|
||||
import { EmailOptions } from '../types/Email';
|
||||
import { getAndCheckPassportByEmail } from '../utils/passport';
|
||||
|
||||
async function makeDistinguishException<ED extends EntityDict>(userId: string, context: BRC<ED>, message?: string) {
|
||||
const [user] = await context.select(
|
||||
|
|
@ -641,6 +642,20 @@ export async function loginByMobile<ED extends EntityDict>(
|
|||
if (captchaRow.expired) {
|
||||
throw new OakUserException('验证码已经过期');
|
||||
}
|
||||
await context.operate(
|
||||
'captcha',
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captchaRow.id!
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
// 到这里说明验证码已经通过
|
||||
return await setupMobile<ED>(mobile, env, context);
|
||||
|
|
@ -762,50 +777,9 @@ export async function loginByAccount<ED extends EntityDict>(
|
|||
assert(account);
|
||||
const accountType = isEmail(account) ? 'email' : (isMobile(account) ? 'mobile' : 'loginName');
|
||||
if (accountType === 'email') {
|
||||
// const application = context.getApplication();
|
||||
// const { system } = application!;
|
||||
// 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: 'email'
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// dontCollect: true,
|
||||
// }
|
||||
// );
|
||||
// assert(applicationPassport?.passport);
|
||||
// const config = applicationPassport.passport.config as EmailConfig;
|
||||
// const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
// assert(emailConfig);
|
||||
// const emailSuffixes = config.emailSuffixes;
|
||||
|
||||
// // 检查邮箱后缀是否满足配置
|
||||
// if (emailSuffixes?.length! > 0) {
|
||||
// let isValid = false;
|
||||
// for (const suffix of emailSuffixes!) {
|
||||
// if (account.endsWith(suffix)) {
|
||||
// isValid = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!isValid) {
|
||||
// throw new OakUserException('error::user.emailSuffixIsInvalid');
|
||||
// }
|
||||
// }
|
||||
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, account);
|
||||
|
||||
const existEmail = await context.select(
|
||||
'email',
|
||||
{
|
||||
|
|
@ -1244,51 +1218,9 @@ export async function loginByEmail<ED extends EntityDict>(
|
|||
}
|
||||
};
|
||||
const closeRootMode = context.openRootMode();
|
||||
const application = context.getApplication();
|
||||
const { system } = application!;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
dontCollect: true,
|
||||
}
|
||||
);
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config as EmailConfig;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length! > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes!) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, email);
|
||||
|
||||
if (!isValid) {
|
||||
throw new OakUserException('邮箱后缀不符合要求')
|
||||
}
|
||||
}
|
||||
if (disableRegister) {
|
||||
const [existEmail] = await context.select(
|
||||
'email',
|
||||
|
|
@ -1359,8 +1291,22 @@ export async function bindByMobile<ED extends EntityDict>(
|
|||
if (captchaRow.expired) {
|
||||
throw new OakUserException('验证码已经过期');
|
||||
}
|
||||
|
||||
// 到这里说明验证码已经通过
|
||||
await context.operate(
|
||||
'captcha',
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captchaRow.id!
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
// 检查当前user是否已绑定mobile
|
||||
const [boundMobile] = await context.select(
|
||||
'mobile',
|
||||
|
|
@ -1379,6 +1325,7 @@ export async function bindByMobile<ED extends EntityDict>(
|
|||
forUpdate: true,
|
||||
}
|
||||
)
|
||||
|
||||
if (boundMobile) {
|
||||
//用户已绑定的mobile与当前输入的mobile一致
|
||||
if (boundMobile.mobile === mobile) {
|
||||
|
|
@ -1567,51 +1514,8 @@ export async function bindByEmail<ED extends EntityDict>(
|
|||
|
||||
const closeRootMode = context.openRootMode();
|
||||
|
||||
const application = context.getApplication();
|
||||
const { system } = application!;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
dontCollect: true,
|
||||
}
|
||||
);
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config as EmailConfig;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, email);
|
||||
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length! > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes!) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new OakUserException('邮箱后缀不符合要求')
|
||||
}
|
||||
}
|
||||
|
||||
const [otherUserEmail] = await context.select(
|
||||
'email',
|
||||
|
|
@ -2730,6 +2634,7 @@ export async function sendCaptchaByMobile<ED extends EntityDict>(
|
|||
'captcha',
|
||||
{
|
||||
filter: {
|
||||
origin: 'mobile',
|
||||
visitorId,
|
||||
$$createAt$$: {
|
||||
$gt: now - 3600 * 1000,
|
||||
|
|
@ -2790,10 +2695,11 @@ export async function sendCaptchaByMobile<ED extends EntityDict>(
|
|||
if (mockSend) {
|
||||
code = mobile.substring(11 - digit);
|
||||
} else {
|
||||
code = Math.floor(Math.random() * Math.pow(10, digit)).toString();
|
||||
while (code.length < digit) {
|
||||
code += '0';
|
||||
}
|
||||
// code = Math.floor(Math.random() * Math.pow(10, digit)).toString();
|
||||
// while (code.length < digit) {
|
||||
// code += '0';
|
||||
// }
|
||||
code = Array.from({ length: digit }, () => Math.floor(Math.random() * 10)).join('');
|
||||
}
|
||||
|
||||
const id = await generateNewIdAsync();
|
||||
|
|
@ -2826,7 +2732,22 @@ export async function sendCaptchaByMobile<ED extends EntityDict>(
|
|||
if (now - (captcha.$$createAt$$! as number) < captchaDuration) {
|
||||
closeRootMode();
|
||||
throw new OakUserException('您的操作太迅捷啦,请稍候再点吧');
|
||||
}
|
||||
}
|
||||
await context.operate(
|
||||
'captcha',
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captcha.id!
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
code = await getCode();
|
||||
} else {
|
||||
code = await getCode();
|
||||
}
|
||||
|
|
@ -2872,54 +2793,11 @@ export async function sendCaptchaByEmail<ED extends EntityDict>(
|
|||
if (type === 'web' || type === 'native') {
|
||||
visitorId = env.visitorId;
|
||||
}
|
||||
const application = context.getApplication();
|
||||
const { system } = application!;
|
||||
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: 'email'
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
dontCollect: true,
|
||||
}
|
||||
);
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config as EmailConfig;
|
||||
const emailConfig = system?.config.Emails?.find((ele) => ele.account === config.account);
|
||||
assert(emailConfig);
|
||||
|
||||
const { config, emailConfig } = await getAndCheckPassportByEmail(context, email);
|
||||
const duration = config.codeDuration || 5;
|
||||
const digit = config.digit || 4;
|
||||
const mockSend = config.mockSend;
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length! > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes!) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new OakUserException('邮箱后缀不符合要求')
|
||||
}
|
||||
}
|
||||
|
||||
let emailOptions: EmailOptions = {
|
||||
// host: emailConfig.host,
|
||||
|
|
@ -2942,6 +2820,7 @@ export async function sendCaptchaByEmail<ED extends EntityDict>(
|
|||
'captcha',
|
||||
{
|
||||
filter: {
|
||||
origin: 'email',
|
||||
visitorId,
|
||||
$$createAt$$: {
|
||||
$gt: now - 3600 * 1000,
|
||||
|
|
@ -3000,10 +2879,11 @@ export async function sendCaptchaByEmail<ED extends EntityDict>(
|
|||
|
||||
const getCode = async () => {
|
||||
let code: string;
|
||||
code = Math.floor(Math.random() * Math.random() * Math.pow(10, digit)).toString();
|
||||
while (code.length < digit) {
|
||||
code += '0';
|
||||
}
|
||||
// code = Math.floor(Math.random() * Math.random() * Math.pow(10, digit)).toString();
|
||||
// while (code.length < digit) {
|
||||
// code += '0';
|
||||
// }
|
||||
code = Array.from({ length: digit }, () => Math.floor(Math.random() * 10)).join('');
|
||||
const id = await generateNewIdAsync();
|
||||
await context.operate(
|
||||
'captcha',
|
||||
|
|
@ -3036,6 +2916,21 @@ export async function sendCaptchaByEmail<ED extends EntityDict>(
|
|||
closeRootMode();
|
||||
throw new OakUserException('您的操作太迅捷啦,请稍候再点吧');
|
||||
}
|
||||
await context.operate(
|
||||
'captcha',
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
expired: true
|
||||
},
|
||||
filter: {
|
||||
id: captcha.id!
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
code = await getCode();
|
||||
} else {
|
||||
code = await getCode();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,47 @@ export default function Web(props: {
|
|||
</Form>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
网站-微信支付
|
||||
</Divider>
|
||||
<Form
|
||||
colon={true}
|
||||
labelAlign="left"
|
||||
layout="vertical"
|
||||
style={{ marginTop: 10 }}
|
||||
>
|
||||
<Form.Item label="appId"
|
||||
//name="appId"
|
||||
>
|
||||
<>
|
||||
<Input
|
||||
placeholder="请输入appId"
|
||||
type="text"
|
||||
value={config?.wechatPay?.appId}
|
||||
onChange={(e) =>
|
||||
setValue(`wechatPay.appId`, e.target.value)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="appSecret"
|
||||
//name="appSecret"
|
||||
>
|
||||
<>
|
||||
<Input
|
||||
placeholder="请输入appSecret"
|
||||
type="text"
|
||||
value={config?.wechatPay?.appSecret}
|
||||
onChange={(e) =>
|
||||
setValue(`wechatPay.appSecret`, e.target.value)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
location
|
||||
|
|
@ -158,62 +199,6 @@ export default function Web(props: {
|
|||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
{/* <Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
网站-授权方式
|
||||
</Divider>
|
||||
<Form
|
||||
colon={true}
|
||||
labelAlign="left"
|
||||
layout="vertical"
|
||||
style={{ marginTop: 10 }}
|
||||
>
|
||||
<Form.Item label="passport"
|
||||
//name="passport"
|
||||
>
|
||||
<>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
placeholder="请选择授权方式"
|
||||
value={config?.passport as Passport[]}
|
||||
onChange={(value: Passport[]) => {
|
||||
if (value.includes('wechat') && value.includes('wechatPublic')) {
|
||||
message.warning('微信网站和微信公众号中,只能选择一个')
|
||||
return;
|
||||
}
|
||||
setValue(`passport`, value);
|
||||
}}
|
||||
options={
|
||||
[
|
||||
{
|
||||
label: '邮箱',
|
||||
value: 'email',
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
value: 'mobile',
|
||||
},
|
||||
{
|
||||
label: '微信网站',
|
||||
value: 'wechat',
|
||||
},
|
||||
{
|
||||
label: '微信公众号',
|
||||
value: 'wechatPublic',
|
||||
},
|
||||
] as Array<{
|
||||
label: string;
|
||||
value: Passport;
|
||||
}>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col> */}
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
|
@ -35,7 +35,6 @@ export default function WechatPublic(props: {
|
|||
const [messageType, setMessageType] = useState('');
|
||||
|
||||
const { config, setValue, cleanKey, removeItem, isService = true } = props;
|
||||
const templateMsgs = config?.templateMsgs || {};
|
||||
return (
|
||||
<Space direction="vertical" size="middle" style={{ display: 'flex' }}>
|
||||
<Row>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ export type WebConfig = {
|
|||
domain?: string;
|
||||
enable?: boolean; //启用扫码登录
|
||||
};
|
||||
wechatPay?: {
|
||||
appId: string;
|
||||
appSecret: string; //微信支付
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http:' | 'https:';
|
||||
|
|
@ -41,7 +45,6 @@ export type WebConfig = {
|
|||
}
|
||||
};
|
||||
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>; // key值代表messageTypeId,value的值代表对应的templateId,data的转换改成message上的函数注入
|
||||
|
||||
export type WechatPublicConfig = {
|
||||
type: 'wechatPublic';
|
||||
|
|
@ -49,7 +52,6 @@ export type WechatPublicConfig = {
|
|||
appId: string;
|
||||
appSecret: string;
|
||||
originalId?: string; //原始id
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
server?: {
|
||||
url?: string; //服务器地址(URL)
|
||||
token: string; //令牌(Token)
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ export type QiniuLiveConfig = {
|
|||
liveHost: string; // 七牛直播云接口域名
|
||||
hub: string; // 直播空间名,
|
||||
publishDomain: string; // 推流域名
|
||||
playDomainType: 'rtmp' | 'hls' | 'flv'; //拉流域名类型
|
||||
playDomainType?: 'rtmp' | 'hls' | 'flv'; //拉流域名类型
|
||||
playDomain: string; // 拉流域名
|
||||
playBackDomain: string; // 直播回放存储域名
|
||||
publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk'; //推流鉴权方式:'none':无校验鉴权;'static':静态鉴权;'expiry':限时鉴权;'expiry_sk':限时鉴权sk
|
||||
publishSecurity?: 'none' | 'static' | 'expiry' | 'expiry_sk'; //推流鉴权方式:'none':无校验鉴权;'static':静态鉴权;'expiry':限时鉴权;'expiry_sk':限时鉴权sk
|
||||
publishKey: string; // 直播空间限时鉴权密钥 用于static和expiry类型的推流鉴权方式 expiry_sk使用accessKey和secretKey
|
||||
playKey: string; // 拉流密钥(防盗链主密钥) 若为空则为未开启防盗链
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export async function getLivestream<ED extends EntityDict & BaseEntityDict, Cxt
|
|||
} = getConfig(context.getApplication()!.system!.config!, 'Live', origin);
|
||||
assert(origin === 'qiniu');
|
||||
const { hub, liveHost, publishDomain, playDomainType, playDomain, playKey, publishKey, publishSecurity } = config as QiniuLiveConfig;
|
||||
const r = await (instance as QiniuCloudInstance).getLiveStream(hub, streamTitle, liveHost, publishDomain, playDomainType, playDomain, expireAt, publishSecurity, publishKey, playKey);
|
||||
const r = await (instance as QiniuCloudInstance).getLiveStream(hub, streamTitle, liveHost, publishDomain, playDomainType!, playDomain, expireAt, publishSecurity!, publishKey, playKey);
|
||||
return {
|
||||
streamTitle,
|
||||
hub,
|
||||
|
|
@ -83,7 +83,7 @@ export async function getStreamObj<ED extends EntityDict & BaseEntityDict, Cxt e
|
|||
|
||||
assert(origin === 'qiniu');
|
||||
const { playDomainType, publishDomain, publishSecurity, publishKey, playDomain, playKey, hub } = config as QiniuLiveConfig;
|
||||
const r = (instance as QiniuCloudInstance).getStreamObj(hub, streamTitle, expireAt, publishDomain, playDomainType, playDomain, publishSecurity, publishKey, playKey);
|
||||
const r = (instance as QiniuCloudInstance).getStreamObj(hub, streamTitle, expireAt, publishDomain, playDomainType!, playDomain, publishSecurity!, publishKey, playKey);
|
||||
return {
|
||||
streamTitle,
|
||||
hub,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
import { EntityDict } from "../oak-app-domain";
|
||||
import { RuntimeCxt, BRC } from "../types/RuntimeCxt";
|
||||
import { EmailConfig } from '../oak-app-domain/Passport/Schema';
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { OakUserException } from 'oak-domain/lib/types';
|
||||
export async function getAndCheckPassportByEmail<ED extends EntityDict>(
|
||||
context: BRC<ED>,
|
||||
email: string
|
||||
) {
|
||||
const application = context.getApplication();
|
||||
const { system } = application!;
|
||||
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: 'email',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
dontCollect: true,
|
||||
}
|
||||
);
|
||||
assert(applicationPassport?.passport);
|
||||
const config = applicationPassport.passport.config as EmailConfig;
|
||||
const emailConfig = system?.config.Emails?.find(
|
||||
(ele) => ele.account === config.account
|
||||
);
|
||||
assert(emailConfig);
|
||||
const emailSuffixes = config.emailSuffixes;
|
||||
|
||||
// 检查邮箱后缀是否满足配置
|
||||
if (emailSuffixes?.length! > 0) {
|
||||
let isValid = false;
|
||||
for (const suffix of emailSuffixes!) {
|
||||
if (email.endsWith(suffix)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new OakUserException('error::user.emailSuffixIsInvalid');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
emailConfig,
|
||||
config
|
||||
};
|
||||
}
|
||||
|
|
@ -118,6 +118,8 @@ export const system: System[] = [
|
|||
publishKey: '',
|
||||
playKey: '',
|
||||
playBackDomain: '',
|
||||
playDomainType: 'rtmp',
|
||||
publishSecurity: 'none',
|
||||
},
|
||||
},
|
||||
Account: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue