application web类型增加微信支付配置

This commit is contained in:
wkj 2025-06-26 18:46:54 +08:00
parent 26bda3c197
commit 641ffd4b1f
24 changed files with 284 additions and 635 deletions

View File

@ -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: {
@ -560,49 +561,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 +939,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: {
@ -1233,46 +1153,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,
@ -2168,49 +2049,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,

View File

@ -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>);
}

View File

@ -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}>

View File

@ -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;

View File

@ -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"> & {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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操作时filtertodo完成
* entity的action的后trigger中调用

7
es/utils/passport.d.ts vendored Normal file
View File

@ -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;
}>;

48
es/utils/passport.js Normal file
View File

@ -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
};
}

View File

@ -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: {
@ -566,49 +567,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 +946,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: {
@ -1242,46 +1162,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,
@ -2185,49 +2066,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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -1,8 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLivestream = getLivestream;
exports.getStreamObj = getStreamObj;
exports.getPlayBackUrl = getPlayBackUrl;
exports.getPlayBackUrl = exports.getStreamObj = exports.getLivestream = void 0;
const assert_1 = require("oak-domain/lib/utils/assert");
const getContextConfig_1 = require("./getContextConfig");
/**
@ -29,6 +27,7 @@ async function getLivestream(params, context) {
expireAt,
};
}
exports.getLivestream = getLivestream;
// 获取推拉流地址
/**
* 直播流已存在的情况下获取推拉流地址
@ -53,6 +52,7 @@ async function getStreamObj(params, context) {
expireAt,
};
}
exports.getStreamObj = getStreamObj;
// 生成直播回放
async function getPlayBackUrl(params, context) {
const { streamTitle, start, end, origin } = params;
@ -61,3 +61,4 @@ async function getPlayBackUrl(params, context) {
const { hub, playBackDomain, liveHost } = config;
return instance.getPlayBackUrl(hub, playBackDomain, streamTitle, start, end, 'POST', liveHost);
}
exports.getPlayBackUrl = getPlayBackUrl;

7
lib/utils/passport.d.ts vendored Normal file
View File

@ -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;
}>;

52
lib/utils/passport.js Normal file
View File

@ -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;

View File

@ -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(
@ -762,50 +763,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 +1204,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',
@ -1567,51 +1485,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',
@ -2872,54 +2747,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,

View File

@ -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>
);
}

View File

@ -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>

View File

@ -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值代表messageTypeIdvalue的值代表对应的templateIddata的转换改成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)

63
src/utils/passport.ts Normal file
View File

@ -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
};
}