...
 
Commits (3)
    https://gitcode.net/vk-uni/vk-uni-cloud-router/-/commit/717bcb49cc94c52c70d6adca60a93e64f69dcf9c 【重要】为了安全性考虑,调整前端的 `vk.request` API,需要手动指定 `uniIdToken: true` 才会自动添加 `token` 到... 2023-07-14T10:59:56+08:00 VK云桌面 370725567@qq.com https://gitcode.net/vk-uni/vk-uni-cloud-router/-/commit/94440434218b1094204dfb8383fb9a4cbe14f5fa 更新依赖 2023-07-19T16:52:00+08:00 VK云桌面 370725567@qq.com https://gitcode.net/vk-uni/vk-uni-cloud-router/-/commit/6fc57570bd40dbbce7d397e2ba338737dc706654 2.15.1 2023-07-20T10:10:58+08:00 VK云桌面 370725567@qq.com
## 2.15.1(2023-07-20)
* 1、【重要】为了安全性考虑,调整前端的 `vk.request` API,需要手动指定 `uniIdToken: true` 才会在请求头中自动添加 `uni-id-token`
* 2、【优化】前端 `vk.request` 当满足响应规范时,会自动保存 `token``userInfo` 以及token失效跳登录页面
* 3、【优化】新增 `vk.baseDao.setById`(根据ID判断存在则修改,不存在则添加,此为原子操作,非查询再判断)
* 4、【优化】`user/pub/sendEmailCode` 发送邮件验证码新增针对同一个邮箱每天的次数限制(默认30次,可在函数内修改默认次数)
* 5、【优化】`user/pub/sendSmsCode` 发送短信验证码新增针对同一个手机号每天的次数限制(默认12次,可在函数内修改默认次数)
##### 框架学习Q群:`22466457` 欢迎萌新和大佬来使用和共同改进框架
## 2.15.0(2023-07-04)
* 1、【重要】注册接口统一去除前端的role参数(需替换目录 `router/service/user/pub`
* 2、【修复】云端表单验证不支持a.b的问题
......
* 1、【重要】注册接口统一去除前端的role参数(需替换目录 `router/service/user/pub`
* 2、【修复】云端表单验证不支持a.b的问题
* 3、【新增】`vk.sessionStorage` 本地会话缓存,仅h5可用
* 4、【优化】`vk.uploadFile` 新增参数 `cloudPathAsRealPath` 默认为true,代表支持阿里云目录
* 5、【优化】`vk.uploadFile` 新增参数 `cloudDirectory` 可以设置上传至指定的云端目录
* 6、【优化】`vk.request` 新增 `interceptor` 参数(该参数仅前端调用时生效)[传送门](https://vkdoc.fsq.pub/client/jsapi.html#vk-request-%E8%AF%B7%E6%B1%82http%E6%8E%A5%E5%8F%A3)
* 7、【优化】发送邮件验证码新增参数判断
* 8、【优化】云函数、云对象404时的错误提示
* 1、【重要】为了安全性考虑,调整前端的 `vk.request` API,需要手动指定 `uniIdToken: true` 才会在请求头中自动添加 `uni-id-token`
* 2、【优化】前端 `vk.request` 当满足响应规范时,会自动保存 `token``userInfo` 以及token失效跳登录页面
* 3、【优化】新增 `vk.baseDao.setById`(根据ID判断存在则修改,不存在则添加,此为原子操作,非查询再判断)
* 4、【优化】`user/pub/sendEmailCode` 发送邮件验证码新增针对同一个邮箱每天的次数限制(默认30次,可在函数内修改默认次数)
* 5、【优化】`user/pub/sendSmsCode` 发送短信验证码新增针对同一个手机号每天的次数限制(默认12次,可在函数内修改默认次数)
##### 框架学习Q群:`22466457` 欢迎萌新和大佬来使用和共同改进框架
\ No newline at end of file
{
"id": "vk-cloud-router",
"displayName": "【开箱即用】vk-unicloud-router - 云函数路由模式开发框架 - 已集成uni-id 框架内置了众多API、工具包,为你的业务扫平障碍。",
"version": "2.15.0",
"version": "2.15.1",
"description": "这是一个unicloud快速开发框架+项目模板(已包含核心库)支持URL化,众多现成API供你使用(登录、注册、短信、微信百度服务端API等等)为你的业务扫平障碍。内置小白也能轻松上手的数据库API。",
"keywords": [
"vk-unicloud-router",
......
......@@ -4,6 +4,7 @@ try {
} catch (err) {
console.error("请先添加公共模块:vk-mail(右键对应的云函数,点击管理公共模块或扩展库依赖,勾选vk-mail依赖)");
}
var everyDaylimit = 30; // 限制同一个邮箱每天次数
module.exports = {
/**
* 发送邮箱验证码
......@@ -13,32 +14,60 @@ module.exports = {
* @param {String} email 邮箱
* @param {String} type 验证码类型
* @param {String} serviceType 邮件服务类型,默认为qq
* @param {Boolean|String} checkUserExist 是否需要检测邮箱对应的账号是否存在或不存在,默认不检测,若为exists代表邮箱必须已注册,若为!exists代表邮箱必须未注册
* res 返回参数说明
* @param {Number} code 错误码,0表示成功
* @param {String} msg 详细信息
* @param {String} email 手机号
* @param {String} verifyCode 验证码
*/
main: async (event) => {
let { data = {}, util } = event;
let { uniID, config } = util;
let {
email,
let {
email,
type,
serviceType = "qq"
serviceType = "qq",
checkUserExist = false
} = data;
let res = { code: 0, msg: 'ok' };
// 业务逻辑开始-----------------------------------------------------------
// 业务逻辑开始-----------------------------------------------------------
if (!vkmail) {
return { code: -1, msg: "请先添加公共模块:vk-mail(右键对应的云函数,点击管理公共模块或扩展库依赖,勾选vk-mail依赖)" };
}
// 参数非空检测
let nullKey = vk.pubfn.isNullOneByObject({ email, type });
if (nullKey) return { code: -1, msg: '参数 '+nullKey+' 不能为空' };
if (vk.pubfn.test(email, "email")) return { code: -1, msg: "邮箱格式错误" };
if (nullKey) return { code: -1, msg: '参数 ' + nullKey + ' 不能为空' };
if (!vk.pubfn.test(email, "email")) return { code: -1, msg: "邮箱格式错误" };
if (vk.pubfn.isNull(type)) return { code: -1, msg: "type不能为空" };
if (checkUserExist) {
let dcloud_appid = originalParam.context.appId;
// 检测邮箱对应的账号是否存在
let num = await vk.daoCenter.userDao.count({
email,
dcloud_appid: _.or(_.eq(dcloud_appid), _.exists(false))
});
if (checkUserExist === true || checkUserExist === "exists") {
// 邮箱必须已注册用户,如果邮箱未注册,则不发短信
if (num === 0) {
return { code: -1, msg: `邮箱:${email} 未注册`, notExists: true };
}
} else if (checkUserExist === "!exists") {
// 邮箱必须未注册用户,如果邮箱已注册,则不发短信
if (num > 0) {
return { code: -1, msg: `邮箱:${email} 已注册`, exists: true };
}
}
}
// 针对同一个邮箱,发送验证码每天有次数限制
const cacheKey = `sys.sendEmailCode.everyDaylimit-${email}`;
let currNum = await vk.globalDataCache.get(cacheKey);
if (!currNum) currNum = 0;
if (currNum >= everyDaylimit) {
return { code: -1, msg: "此邮箱今日已超最大次数限制,请明日再试" };
}
let code = vk.pubfn.random(6, "0123456789");
let param = {
code,
......@@ -61,11 +90,16 @@ module.exports = {
"from": emailConfig[serviceType].auth.user,
"to": data.email,
"cc": emailConfig[serviceType].auth.user, // 由于邮件可能会被当成垃圾邮件,但只要把邮件抄送给自己一份,就不会被当成垃圾邮件。
"subject": data.subject, // 邮件的标题
"text": `您的验证码是${code},打死也不要告诉别人哦!`, // 邮件的内容
"subject": data.subject || `验证码是${code}`, // 邮件的标题
"text": `您的验证码是${code},打死也不要告诉别人哦!`, // 邮件的内容
});
// 发送验证码成功后,设置验证码
await uniID.setVerifyCode(param);
currNum++;
let { startTime } = vk.pubfn.getDayOffsetStartAndEnd(1, new Date());
let second = vk.pubfn.toDecimal((startTime - Date.now()) / 1000, 0)
await vk.globalDataCache.set(cacheKey, currNum, second);
} catch (err) {
console.error(err);
return { code: -1, msg: "邮件发送失败", err };
......@@ -75,4 +109,4 @@ module.exports = {
// 业务逻辑结束-----------------------------------------------------------
return res;
}
}
}
\ No newline at end of file
var everyDaylimit = 12; // 限制同一个手机号每天次数
module.exports = {
/**
* 发送短信的验证码
......@@ -6,7 +7,7 @@ module.exports = {
* data 请求参数 说明
* @param {String} mobile 手机号
* @param {String} type 验证码类型
* @param {Boolean} checkUserExist 是否需要检测手机号对应的账号是否存在,默认false:不检测 设置为true:会检测,如果检测到用户不存在,则不发短信。
* @param {Boolean|String} checkUserExist 是否需要检测手机号对应的账号是否存在或不存在,默认不检测,若为exists代表手机号必须已注册,若为!exists代表手机号必须未注册
*
* res 返回参数说明
* @param {Number} code 错误码,0表示成功
......@@ -20,13 +21,18 @@ module.exports = {
let { uid } = data;
let res = { code: 0, msg: '' };
// 业务逻辑开始-----------------------------------------------------------
let { mobile, type, checkUserExist = false } = data;
let {
mobile,
type,
checkUserExist = false
} = data;
if (vk.pubfn.isNull(mobile)) {
return { code: -1, msg: '手机号不能为空' };
}
if (!vk.pubfn.test(mobile, 'mobile')) {
return { code: -1, msg: "手机号格式错误" };
}
if (checkUserExist) {
let dcloud_appid = originalParam.context.appId;
// 检测手机号对应的账号是否存在
......@@ -34,10 +40,28 @@ module.exports = {
mobile,
dcloud_appid: _.or(_.eq(dcloud_appid), _.exists(false))
});
if (num === 0) {
return { code: -1, msg: `手机号:${mobile} 未注册`, notExists:true };
if (checkUserExist === true || checkUserExist === "exists") {
// 手机号必须已注册用户,如果手机号未注册,则不发短信
if (num === 0) {
return { code: -1, msg: `手机号:${mobile} 未注册`, notExists: true };
}
} else if (checkUserExist === "!exists") {
// 手机号必须未注册用户,如果手机号已注册,则不发短信
if (num > 0) {
return { code: -1, msg: `手机号:${mobile} 已注册`, exists: true };
}
}
}
// 针对同一个手机号,发送验证码每天有次数限制
const cacheKey = `sys.sendSmsCode.everyDaylimit-${mobile}`;
let currNum = await vk.globalDataCache.get(cacheKey);
if (!currNum) currNum = 0;
if (currNum >= everyDaylimit) {
return { code: -1, msg: "此手机号今日已超最大次数限制,请明日再试" };
}
let code = vk.pubfn.random(6, "0123456789");
let provider = "unicloud";
if (vk.pubfn.getData(config, "vk.service.sms.aliyun.enable")) {
......@@ -50,7 +74,13 @@ module.exports = {
phone: mobile,
expiresIn: 180, // 验证码实际有效时间,必须是60的倍数
});
if (res.code == 0) {
currNum++;
let { startTime } = vk.pubfn.getDayOffsetStartAndEnd(1, new Date());
let second = vk.pubfn.toDecimal((startTime - Date.now()) / 1000, 0)
await vk.globalDataCache.set(cacheKey, currNum, second);
}
// 业务逻辑结束-----------------------------------------------------------
return res;
}
}
}
\ No newline at end of file
## 2.15.1(2023-07-20)
* 1、【重要】为了安全性考虑,调整前端的 `vk.request` API,需要手动指定 `uniIdToken: true` 才会在请求头中自动添加 `uni-id-token`
* 2、【优化】前端 `vk.request` 当满足响应规范时,会自动保存 `token``userInfo` 以及token失效跳登录页面
* 3、【优化】新增 `vk.baseDao.setById`(根据ID判断存在则修改,不存在则添加,此为原子操作,非查询再判断)
* 4、【优化】`user/pub/sendEmailCode` 发送邮件验证码新增针对同一个邮箱每天的次数限制(默认30次,可在函数内修改默认次数)
* 5、【优化】`user/pub/sendSmsCode` 发送短信验证码新增针对同一个手机号每天的次数限制(默认12次,可在函数内修改默认次数)
* 完整框架项目地址:`https://ext.dcloud.net.cn/plugin?id=2204`[点击查看](https://ext.dcloud.net.cn/plugin?id=2204)
## 2.15.0(2023-07-04)
* 1、【重要】注册接口统一去除前端的role参数(需替换目录 `router/service/user/pub`
* 2、【修复】云端表单验证不支持a.b的问题
......
{
"id": "vk-unicloud",
"displayName": "vk-unicloud-router开发框架核心库 - 已集成uni-id 框架内置了众多API。",
"version": "2.15.0",
"version": "2.15.1",
"description": "此为vk-unicloud-router框架核心库(新手建议下载完整框架项目)已集成uni-id支持云函数url化。众多现成API,内置小白也能轻松上手的数据库API。使你项目刚起步进度就是百分之50",
"keywords": [
"vk-unicloud-router",
......
{
"name": "vk-unicloud",
"version": "2.15.0",
"version": "2.15.1",
"description": "【云函数端SDK】VK云函数路由模式uniCloud开发框架,在router目录下执行 npm i vk-unicloud 进行安装和升级",
"main": "index.js",
"homepage": "https://gitee.com/vk-uni/vk-uni-cloud-router.git",
......
......@@ -2060,6 +2060,7 @@ vk.pubfn.fileToBase64({ file }).then(base64 => {
*/
pubfn.fileToBase64 = function(obj = {}) {
let { file } = obj;
let filePath = typeof file === "object" ? file.path : file;
return new Promise(function(resolve, reject) {
// #ifdef H5
let reader = new FileReader();
......@@ -2081,7 +2082,7 @@ pubfn.fileToBase64 = function(obj = {}) {
// #endif
// #ifdef MP
uni.getFileSystemManager().readFile({
filePath: file.path,
filePath: filePath,
encoding: "base64",
success: function(res) {
let base64 = res.data;
......@@ -2104,7 +2105,7 @@ pubfn.fileToBase64 = function(obj = {}) {
// resolve(base64);
// #endif
// #ifdef APP-PLUS
plus.io.resolveLocalFileSystemURL(pubfn.getLocalFilePath(file.path), function(entry) {
plus.io.resolveLocalFileSystemURL(pubfn.getLocalFilePath(filePath), function(entry) {
entry.file(function(file) {
let fileReader = new plus.io.FileReader();
fileReader.onload = function(data) {
......
......@@ -108,8 +108,14 @@ requestUtil.request = function(obj = {}) {
}
// 自动注入token到请求头开始-----------------------------------------------------------
if (typeof vk.getToken === "function") {
let uni_id_token = vk.getToken();
// 注意:自2.15.1开始,需要手动指定uniIdToken: true 才会自动添加token到请求头里
if (typeof vk.getToken === "function" && obj.uniIdToken) {
let uni_id_token;
if (obj.uniIdToken === true) {
uni_id_token = vk.getToken();
} else if (typeof obj.uniIdToken === "boolean") {
uni_id_token = obj.uniIdToken;
}
if (uni_id_token) {
if (!obj.header) obj.header = {};
obj.header["uni-id-token"] = uni_id_token;
......@@ -220,7 +226,18 @@ function requestSuccess(obj = {}) {
}
}
if (config.debug) Logger.result = (typeof data == "object") ? vk.pubfn.copyObject(data) : data;
if (res.statusCode >= 400 || data.code) {
if ([1301, 1302, 30201, 30202, 30203, 30204].indexOf(data.code) > -1 && data.msg.indexOf("token") > -1) {
// 执行 login 拦截器函数(跳转到页面页面)
let { interceptor = {} } = vk.callFunctionUtil;
if (typeof interceptor.login === "function") {
interceptor.login({
res: data,
params,
vk
});
}
reject(data);
} else if (res.statusCode >= 400 || data.code) {
requestFail({
res: data,
params,
......