Files
t/uniCloud-alipay/cloudfunctions/user-info/index.obj.js
T
2025-06-13 20:46:10 +08:00

197 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const db = uniCloud.database();
const _ = db.command;
const crypto = require('crypto');
let obj = {
isValidIP(ip) {
// ------------------------- IPv4 验证 -------------------------
if (ip.includes('.')) {
const ipv4Regex = /^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/;
return ipv4Regex.test(ip); // 直接通过正则匹配[1,5](@ref)
}
// ------------------------- IPv6 验证 -------------------------
if (ip.includes(':')) {
const parts = ip.split(':');
// 处理压缩的::符号(如::1或2001:db8::1)
const hasDoubleColon = ip.includes('::');
if (hasDoubleColon && ip.indexOf('::') !== ip.lastIndexOf('::')) return false; // 禁止多个::[6](@ref)
// 分割后的段数应在1到8之间(允许压缩)
if (parts.length < 3 || parts.length > 8) return false;
// 展开压缩段(如将::替换为填充段)
let expandedParts = [];
let fillZeros = 8 - parts.filter(p => p !== '').length;
for (let part of parts) {
if (part === '') {
while (fillZeros-- > 0) expandedParts.push('0');
} else {
expandedParts.push(part);
}
}
if (expandedParts.length !== 8) return false;
// 验证每段是否为1-4位十六进制字符
const hexRegex = /^[0-9a-fA-F]{1,4}$/;
return expandedParts.every(p => hexRegex.test(p)); // 每段必须符合规则[6,7](@ref)
}
return false;
},
isReservedOrLocalIP(ip) {
if (ip.includes('.')) {
const parts = ip.split('.').map(Number);
if (parts.length !== 4 || parts.some(n => n < 0 || n > 255)) return false;
if (
parts[0] === 10 ||
(parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) ||
(parts[0] === 192 && parts[1] === 168)
) return true;
return (
parts[0] === 127 ||
(parts[0] === 169 && parts[1] === 254) ||
(parts[0] >= 224 && parts[0] <= 239) ||
ip === '0.0.0.0' ||
ip === '255.255.255.255'
);
}
// IPv6 处理逻辑
if (ip.includes(':')) {
const normalized = ip.replace(/(^:|:$)/g, '::').replace(/::/g, ':0:').split(':')
.map(seg => seg.padStart(4, '0')).join(':').padStart(39, '0:');
if (normalized.startsWith('fc00:') || normalized.startsWith('fd00:')) return true;
return (
normalized === '0000:0000:0000:0000:0000:0000:0000:0001' ||
normalized.startsWith('fe80:') ||
normalized.startsWith('ff00:') ||
normalized.startsWith('2001:0db8:') ||
normalized === '0000:0000:0000:0000:0000:0000:0000:0000'
);
}
return false;
},
async getIPAddress(ip) {
if (!obj.isValidIP(ip)) return "未知";
if (obj.isReservedOrLocalIP(ip)) return "未知";
let address = "";
const res = await db.collection("ip").where({
ip: ip
})
.field({
ip:true,
country: true,
economize: true,
market: true,
})
.get();
console.log(res);
if (res.data.length > 0) {
address = res.data.city;
}
let key = "IPUBZ-ZWF6I-PQ4GR-56NKD-BLZYJ-YHFIY";
let requests = "/ws/location/v1/ip?ip=" + ip + "&key="+ key+ "&output=json";
let sk = "1YTD18oU9wjLtVTVJWYupigJjuTPGvae";
const sig = crypto.createHash('md5')
.update(requests+sk)
.digest("hex");
console.log(sig)
let url= "https://apis.map.qq.com"+ requests + "&sig=" + sig;
console.log(url);
const response = await uniCloud.httpclient.request(url, {
method: 'GET',
});
console.log(response);
console.log(response.data)
if (response.status === 200) {
let json = JSON.parse(response.data.toString('utf8'));
if (json.message==="Success") {
await db.collection("ip").add({...json.result});
address = json.result.ad_info.province + " " + json.result.ad_info.city;
console.log(address)
return address;
}
}
return "未知";
}
}
module.exports = {
_before: function () { // 通用预处理器
},
async getIP(query) {
try {
let { uid } = query;
let res = await db.collection("uni-id-users")
.doc(uid)
.field({
_id: 1,
last_login_ip: 1
})
.get();
console.log(res.data[0]);
return {
code: 200,
data: res.data[0]
}
} catch(e) {
return {
code: 500,
msg: e.message
}
}
},
async get_user_info(query) {
try {
let uid = query.uid;
console.log(uid);
if (!uid) throw new Error("uid不存在");
console.log(uid);
let res = await db.collection("uni-id-users")
.doc(uid)
.field({
_id: 1,
nickname: 1,
avatar_file: 1,
last_login_ip:1,
register_date: 1,
last_login_date:1,
personal_profile: 1,
gender: 1
})
.get();
console.log(res.data[0].last_login_ip)
res.data[0].last_login_ip = await obj.getIPAddress(res.data[0].last_login_ip);
console.log(res)
return {
code: 200,
data: res.data[0]
}
} catch (e) {
console.log(e);
return {
code: 500,
msg: e.message
}
}
}
}