Files
t/uniCloud-alipay/cloudfunctions/user-info/index.obj.js
T
2025-03-21 09:38:06 +08:00

186 lines
5.7 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;
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) {
// ------------------------- IPv4 处理逻辑 -------------------------
if (ip.includes('.')) {
const parts = ip.split('.').map(Number);
// 格式验证
if (parts.length !== 4 || parts.some(n => n < 0 || n > 255)) return false;
// 1. 局域网地址(私有地址)
if (
parts[0] === 10 || // 10.0.0.0/8 [1,2,4](@ref)
(parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) || // 172.16.0.0/12 [1,2,4](@ref)
(parts[0] === 192 && parts[1] === 168) // 192.168.0.0/16 [1,2,4](@ref)
) return true;
// 2. 保留地址
return (
parts[0] === 127 || // 127.0.0.0/8(环回地址)[1,4](@ref)
(parts[0] === 169 && parts[1] === 254) || // 169.254.0.0/16(链路本地地址)[4,5](@ref)
(parts[0] >= 224 && parts[0] <= 239) || // 224.0.0.0/4(多播地址)[3,5](@ref)
ip === '0.0.0.0' || // 未指定地址 [1](@ref)
ip === '255.255.255.255' // 广播地址 [1](@ref)
);
}
// ------------------------- IPv6 处理逻辑 -------------------------
if (ip.includes(':')) {
// 规范化IPv6(展开缩写)
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;
// 2. 保留地址
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 uniCloud.collection("ip").where({
ip: ip
})
.get();
console.log(res);
if (res.data.length > 0) {
const res = await uniCloud.collection("ip").where({
ip: ip
})
.field({
ip:true,
country: true,
economize: true,
market: true,
})
.get();
if (res.data[0].market === "") address = res.data[0].country + " " + res.data[0].economize;
else {
address = res.data[0].economize + " " + res.data[0].market;
}
return address;
}
let url= "https://62cccca0.api.cn/ipdata?token=7cec107b2f759a84211c74d9d9d6b4c4&datatype=json&ip=" + ip;
const response = await uniCloud.httpclient.request(url, {
method: 'GET',
timeout: 1000
});
console.log(response);
if (response.status === 200) {
await uniCloud.collection("ip").add({
ip: response.data.ip,
country: response.data.data[0]==="台湾"?"中国台湾":response.data.data[0],
economize: response.data.data[1],
market: response.data.data[2],
county: response.data.data[3],
operator: response.data.data[4],
postal_code: response.data.data[5],
area_code: response.data.data[6],
network: response.data.data[7]
});
if (response.data.data[2] === "" ) {
address = response.data.data[0] + " " + response.data.data[1];
}else {
address = response.data.data[1] + " " + response.data.data[2];
}
return address;
}
return address;
}
}
module.exports = {
_before: function () { // 通用预处理器
},
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: true,
nickname: true,
avatar_file: true,
last_login_ip:true,
register_date: true,
last_login_date:true,
personal_profile: true,
gender: true
})
.get();
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
}
}
}
}