remove mark

This commit is contained in:
2025-12-04 10:31:37 +08:00
parent 46aa293cce
commit 2a55f2d3ef
35 changed files with 1837 additions and 726 deletions

View File

@@ -0,0 +1,261 @@
import { DataTypes, Model, Sequelize } from 'sequelize';
import { useContextKey } from '@kevisual/context';
import { Redis } from 'ioredis';
import { SyncOpts, User } from './user.ts';
import { oauth } from '../oauth/auth.ts';
import { OauthUser } from '../oauth/oauth.ts';
export const redis = useContextKey<Redis>('redis');
const UserSecretStatus = ['active', 'inactive', 'expired'] as const;
type Data = {
[key: string]: any;
/**
* 微信开放平台的某一个应用的openid
*/
wxOpenid?: string;
/**
* 微信开放平台的unionid主要
*/
wxUnionid?: string;
/**
* 微信公众号的openid次要
*/
wxmpOpenid?: string;
}
export class UserSecret extends Model {
static oauth = oauth;
declare id: string;
declare token: string;
declare userId: string;
declare orgId: string;
declare title: string;
declare description: string;
declare status: (typeof UserSecretStatus)[number];
declare expiredTime: Date;
declare data: Data;
/**
* 验证token
* @param token
* @returns
*/
static async verifyToken(token: string) {
if (!oauth.isSecretKey(token)) {
return await oauth.verifyToken(token);
}
// const secretToken = await oauth.verifyToken(token);
// if (secretToken) {
// return secretToken;
// }
const userSecret = await UserSecret.findOne({
where: { token },
});
if (!userSecret) {
return null; // 如果没有找到对应的用户密钥则返回null
}
if (userSecret.isExpired()) {
return null; // 如果用户密钥已过期则返回null
}
if (userSecret.status !== 'active') {
return null; // 如果用户密钥状态不是active则返回null
}
// 如果用户密钥未过期,则返回用户信息
const oauthUser = await userSecret.getOauthUser();
if (!oauthUser) {
return null; // 如果没有找到对应的oauth用户则返回null
}
// await oauth.saveSecretKey(oauthUser, userSecret.token);
// 存储到oauth中的token store中
return oauthUser;
}
/**
* owner 组织用户的 oauthUser
* @returns
*/
async getOauthUser() {
const user = await User.findOne({
where: { id: this.userId },
attributes: ['id', 'username', 'type', 'owner'],
});
let org: User = null;
if (!user) {
return null; // 如果没有找到对应的用户则返回null
}
const expiredTime = this.expiredTime ? new Date(this.expiredTime).getTime() : null;
const oauthUser: Partial<OauthUser> = {
id: user.id,
username: user.username,
type: 'user',
oauthExpand: {
expiredTime: expiredTime,
},
};
if (this.orgId) {
org = await User.findOne({
where: { id: this.orgId },
attributes: ['id', 'username', 'type', 'owner'],
});
if (org) {
oauthUser.id = org.id;
oauthUser.username = org.username;
oauthUser.type = 'org';
oauthUser.uid = user.id;
} else {
console.warn(`getOauthUser: org not found for orgId ${this.orgId}`);
}
}
return oauth.getOauthUser(oauthUser);
}
isExpired() {
if (!this.expiredTime) {
return false; // 没有设置过期时间
}
const now = Date.now();
const expiredTime = new Date(this.expiredTime);
return now > expiredTime.getTime(); // 如果当前时间大于过期时间,则认为已过期
}
async createNewToken() {
if (this.token) {
await oauth.delToken(this.token);
}
const token = await UserSecret.createToken();
this.token = token;
await this.save();
return token;
}
static async createToken() {
let token = oauth.generateSecretKey();
// 确保生成的token是唯一的
while (await UserSecret.findOne({ where: { token } })) {
token = oauth.generateSecretKey();
}
return token;
}
static async createSecret(tokenUser: { id: string; uid?: string }, expireDay = 365) {
const expireTime = expireDay * 24 * 60 * 60 * 1000; // 转换为毫秒
const token = await UserSecret.createToken();
let userId = tokenUser.id;
let orgId: string = null;
if (tokenUser.uid) {
userId = tokenUser.uid;
orgId = tokenUser.id; // 如果是组织用户则uid是组织ID
}
const userSecret = await UserSecret.create({
userId,
orgId,
token,
expiredTime: new Date(Date.now() + expireTime),
});
return userSecret;
}
async getPermission(opts: { id: string; uid?: string }) {
const { id, uid } = opts;
let userId: string = id;
let hasPermission = false;
let isUser = false;
let isAdmin: boolean = null;
if (uid) {
userId = uid;
}
if (!id) {
return {
hasPermission,
isUser,
isAdmin,
};
}
if (this.userId === userId) {
hasPermission = true;
isUser = true;
}
if (hasPermission) {
return {
hasPermission,
isUser,
isAdmin,
};
}
if (this.orgId) {
const orgUser = await User.findByPk(this.orgId);
if (orgUser && orgUser.owner === userId) {
isAdmin = true;
hasPermission = true;
}
}
return {
hasPermission,
isUser,
isAdmin,
};
}
}
/**
* 组织模型在sequelize之后初始化
*/
export const UserSecretInit = async (newSequelize?: any, tableName?: string, sync?: SyncOpts) => {
const sequelize = useContextKey<Sequelize>('sequelize');
UserSecret.init(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
description: {
type: DataTypes.TEXT,
allowNull: true,
},
status: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: 'active',
comment: '状态',
},
title: {
type: DataTypes.TEXT,
allowNull: true,
},
expiredTime: {
type: DataTypes.DATE,
allowNull: true,
},
token: {
type: DataTypes.STRING,
allowNull: false,
comment: '用户密钥',
defaultValue: '',
},
userId: {
type: DataTypes.UUID,
allowNull: true,
},
data: {
type: DataTypes.JSONB,
allowNull: true,
defaultValue: {},
},
orgId: {
type: DataTypes.UUID,
allowNull: true,
comment: '组织ID',
},
},
{
sequelize: newSequelize || sequelize,
modelName: tableName || 'cf_user_secret',
},
);
if (sync) {
await UserSecret.sync({ alter: true, logging: false, ...sync }).catch((e) => {
console.error('UserSecret sync', e);
});
return UserSecret;
}
return UserSecret;
};
export const UserSecretModel = useContextKey('UserSecretModel', () => UserSecret);